kwave  18.07.70
MP3EncoderDialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  MP3EncoderDialog.cpp - dialog for configuring the MP3 encoer
3  -------------------
4  begin : Sun Jun 03 2012
5  copyright : (C) 2012 by Thomas Eschenbacher
6  email : Thomas.Eschenbacher@gmx.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "config.h"
19 
20 #include <QAbstractButton>
21 #include <QApplication>
22 #include <QBuffer>
23 #include <QCursor>
24 #include <QDialogButtonBox>
25 #include <QDir>
26 #include <QFile>
27 #include <QFileInfo>
28 #include <QLatin1Char>
29 #include <QPointer>
30 #include <QProcess>
31 #include <QPushButton>
32 #include <QtGlobal>
33 #include <QLineEdit>
34 
35 #include <KHelpClient>
36 #include <KProcess>
37 
38 #include "libkwave/FileInfo.h"
39 #include "libkwave/MessageBox.h"
40 #include "libkwave/MetaDataList.h"
42 #include "libkwave/ReaderMode.h"
43 #include "libkwave/SignalManager.h"
44 #include "libkwave/String.h"
45 #include "libkwave/Utils.h"
46 
47 #include "libgui/FileDialog.h"
48 
49 #include "MP3Encoder.h"
50 #include "MP3EncoderDialog.h"
51 #include "MP3EncoderSettings.h"
52 
54 #define PRESET_NAME_USER_DEFINED i18n("(user defined)")
55 
56 #ifdef EXECUTABLE_SUFFIX
57 #define EXE_SUFFIX EXECUTABLE_SUFFIX
58 #else
59 #define EXE_SUFFIX ""
60 #endif
61 
66 {
67  {
68  _("LAME"), // name
69  _("lame" EXE_SUFFIX), // path
70  {
71  _("-r"), // raw format
72 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
73  _("--big-endian"), // byte order
74 #else
75  _("--little-endian"), // byte order
76 #endif
77  _("--signed") // signed
78  },
79  {
80  _("-s %1"), // sample rate
81  _("--bitwidth %1"), // bits per sample
82  {
83  _("-mm"), // mono
84  _("-mj") // stereo
85  }
86  },
87  {
88  {
89  _("--abr %1"), // average bitrate
90  _("-b %1"), // minimum bitrate
91  _("-B %1") // maximum bitrate
92  }
93  },
94  {
95  {
96  _("-en"), // no emphasis
97  _("-e5"), // 50/15ms
98  _("-ec") // CCIT J17
99  },
100  _("-q 2"), // noise shaping
101  _("--strictly-enforce-ISO") // compatibility
102  },
103  {
104  _("-c"), // copyrighted
105  _("-o"), // original
106  _("-p"), // protect
107  _(""), // prepended
108  _("--silent") // appended
109  },
110  {
111  _("--longhelp"), // encoder help
112  _("--version") // encoder version
113  }
114  },
115  /***********************************************************************/
116  {
117  _("TwoLAME"), // name
118  _("twolame" EXE_SUFFIX), // path
119  {
120  _("--raw-input"), // raw format
121 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
122  _("--byte-swap"), // byte order
123 #else
124  _(""), // byte order
125 #endif
126  _("") // signed
127  },
128  {
129  _("--samplerate=%1"), // sample rate
130  _("--samplesize=16"), // bits per sample (supports only 16)
131  {
132  _("--channels=1 --mode=mono"), // mono
133  _("--channels=2 --mode=joint") // stereo
134  }
135  },
136  {
137  {
138  _("--bitrate=%1"), // average bitrate
139  _(""), // minimum bitrate
140  _("--max-bitrate=%1") // maximum bitrate
141  }
142  },
143  {
144  {
145  _("--deemphasis=n"), // no emphasis
146  _("--deemphasis=5"), // 50/15ms
147  _("--deemphasis=c") // CCIT J17
148  },
149  _(""), // noise shaping
150  _("") // compatibility
151  },
152  {
153  _("--copyright"), // copyrighted
154  _("--original"), // original
155  _("--protect"), // protect
156  _(""), // prepended
157  _("--quiet") // appended
158  },
159  {
160  _("--help"), // encoder help
161  _("--help") // encoder version
162  }
163  },
164  /***********************************************************************/
165  {
166  _("tooLAME"), // name
167  _("toolame" EXE_SUFFIX), // path
168  {
169  _(""), // raw format
170 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
171  _("-x"), // byte order
172 #else
173  _(""), // byte order
174 #endif
175  _("") // signed
176  },
177  {
178  _("-s [%khz]"), // sample rate
179  _(""), // bits per sample (supports only 16)
180  {
181  _("-mm"), // mono
182  _("-mj") // stereo
183  }
184  },
185  {
186  {
187  _("-b %1"), // average bitrate
188  _(""), // minimum bitrate
189  _("") // maximum bitrate
190  }
191  },
192  {
193  {
194  _("-dn"), // no emphasis
195  _("-d5"), // 50/15ms
196  _("-dc") // CCIT J17
197  },
198  _(""), // noise shaping
199  _("") // compatibility
200  },
201  {
202  _("-c"), // copyrighted
203  _("-o"), // original
204  _("-e"), // protect
205  _(""), // prepended
206  _("-t 0") // appended
207  },
208  {
209  _("-help"), // encoder help
210  _("-version") // encoder version
211  }
212  }
213 };
214 
215 /***************************************************************************/
216 
222 #define LOAD(field, control) control->setText(m_settings.field)
223 
229 #define SAVE(field, control) \
230  m_settings.field = QString(control->text()).simplified()
231 
237 #define CONNECT(control) \
238  connect(control, SIGNAL(editingFinished()), \
239  this, SLOT(switchToUserDefined()))
240 
248 #define CHECK(field, control) match &= \
249  (settings.field == QString(control->text()).simplified())
250 
251 #define ELEMENTS_OF(x) (sizeof(x) / sizeof(x[0]))
252 
253 /***************************************************************************/
255  :QDialog(parent), Ui::MP3EncoderDialogBase(),
256  m_settings(g_predefined_settings[0])
257 {
258  setupUi(this);
259  setModal(true);
260 
261  // set up the combo box with all presets
262  cbProgram->clear();
263  for (unsigned int i = 0; i < ELEMENTS_OF(g_predefined_settings); i++) {
264  QString name = g_predefined_settings[i].m_name;
265  QString path = searchPath(g_predefined_settings[i].m_path);
266  QString param = g_predefined_settings[i].m_info.m_version;
267  QString version = encoderVersion(path, param);
268  if (version.length() >= name.length())
269  cbProgram->addItem(version);
270  else
271  cbProgram->addItem(name);
272  }
273  cbProgram->addItem(PRESET_NAME_USER_DEFINED);
274 
275  // load the saved settings from the config file
276  m_settings.load();
277  load();
278 
279  // connect the combo box of the program selection
280  connect(cbProgram, SIGNAL(activated(int)),
281  this, SLOT(selectProgram(int)));
282 
283  // standard actions, reset / reset to defaults etc...
284  connect(buttonBox, SIGNAL(clicked(QAbstractButton*)),
285  this, SLOT(buttonClicked(QAbstractButton*)));
286  connect(buttonBox_Help, SIGNAL(helpRequested()),
287  this, SLOT(invokeHelp()));
288 
289  // auto-detect button
290  connect(btDetect, SIGNAL(clicked()), this, SLOT(autoDetect()));
291 
292  // locate file path button
293  connect(btLocate, SIGNAL(clicked()), this, SLOT(locatePath()));
294 
295  // search for program (file browser)
296  connect(btSearch, SIGNAL(clicked()), this, SLOT(browseFile()));
297 
298  // test setup
299  connect(btTest, SIGNAL(clicked()), this, SLOT(testSettings()));
300 
301  // builtin help of the encoder
302  connect(btEncoderHelp, SIGNAL(clicked()), this, SLOT(encoderHelp()));
303 
304  // whenever a setting has been manally edited, check if that is a
305  // user defined setting or a predefined set of parameters
306  CONNECT(edPath);
307 
308  CONNECT(edRawFormat);
309  CONNECT(edByteOrder);
310  CONNECT(edSign);
311 
312  CONNECT(edSampleRate);
313  CONNECT(edBitsPerSample);
314  CONNECT(edMono);
315  CONNECT(edStereo);
316 
317  CONNECT(edBitrateAvg);
318  CONNECT(edBitrateMin);
319  CONNECT(edBitrateMax);
320 
321  CONNECT(edEmphasisNone);
322  CONNECT(edEmphasis5015ms);
323  CONNECT(edEmphasisCCIT_J17);
324 
325  CONNECT(edNoiseShaping);
326  CONNECT(edCompatibility);
327 
328  CONNECT(edCopyright);
329  CONNECT(edOriginal);
330  CONNECT(edProtect);
331  CONNECT(edPrepend);
332  CONNECT(edAppend);
333 
334  CONNECT(edEncoderHelp);
335  CONNECT(edVersionInfo);
336 
337  // set up all tool tips which contain a % character right here instead
338  // of the ui file, as they they would trigger errors during
339  // extraction (I18N_ARGUMENT_MISSING)
340  edSampleRate->setToolTip(i18n(
341  "sample rate in Hz (use %1 as placeholder)\n"
342  "or kHz (use %2 as placeholder)",
343  _("%1"), _("[%khz]")));
344  edBitsPerSample->setToolTip(i18n(
345  "bits per sample,\n"
346  "use %1 as placeholder",
347  _("%1")));
348  edBitrateMin->setToolTip(i18n(
349  "parameter for minimum bitrate in bits/sec\n"
350  "(use %1 as placeholder)",
351  _("%1")));
352  edBitrateMax->setToolTip(i18n(
353  "parameter for maximum bitrate in bits/sec\n"
354  "(use %1 as placeholder)",
355  _("%1")));
356  edBitrateAvg->setToolTip(i18n(
357  "parameter for average bitrate in bits/sec\n"
358  "(use %1 as placeholder)",
359  _("%1")));
360 
361  // set the focus onto the "OK" button
362  buttonBox->button(QDialogButtonBox::Ok)->setFocus();
363 }
364 
365 /***************************************************************************/
367 {
368 }
369 
370 /***************************************************************************/
372 {
373  // cbProgram
374  unsigned int i = 0;
375  bool use_preset = false;
376  for (i = 0; i < ELEMENTS_OF(g_predefined_settings); i++) {
377  if (g_predefined_settings[i].m_name == m_settings.m_name) {
378  QString path = m_settings.m_path;
379  m_settings = g_predefined_settings[i];
380  m_settings.m_path = path;
381  cbProgram->setCurrentIndex(i);
382  use_preset = true;
383  break;
384  }
385  }
386  if ((!use_preset) && (cbProgram->currentIndex() != Kwave::toInt(i))) {
387  // set the combo box to "user defined" and load the rest from the config
388  cbProgram->setCurrentIndex(i);
389  }
390 
391  // set all other dialog content according to the loaded settings
392  LOAD(m_path, edPath);
393 
394  LOAD(m_input.m_raw_format, edRawFormat);
395  LOAD(m_input.m_byte_order, edByteOrder);
396  LOAD(m_input.m_signed, edSign);
397 
398  LOAD(m_format.m_sample_rate, edSampleRate);
399  LOAD(m_format.m_bits_per_sample, edBitsPerSample);
400  LOAD(m_format.m_channels.m_mono, edMono);
401  LOAD(m_format.m_channels.m_stereo, edStereo);
402 
403  LOAD(m_quality.m_bitrate.m_avg, edBitrateAvg);
404  LOAD(m_quality.m_bitrate.m_min, edBitrateMin);
405  LOAD(m_quality.m_bitrate.m_max, edBitrateMax);
406 
407  LOAD(m_encoding.m_emphasis.m_none, edEmphasisNone);
408  LOAD(m_encoding.m_emphasis.m_50_15ms, edEmphasis5015ms);
409  LOAD(m_encoding.m_emphasis.m_ccit_j17, edEmphasisCCIT_J17);
410 
411  LOAD(m_encoding.m_noise_shaping, edNoiseShaping);
412  LOAD(m_encoding.m_compatibility, edCompatibility);
413 
414  LOAD(m_flags.m_copyright, edCopyright);
415  LOAD(m_flags.m_original, edOriginal);
416  LOAD(m_flags.m_protect, edProtect);
417  LOAD(m_flags.m_prepend, edPrepend);
418  LOAD(m_flags.m_append, edAppend);
419 
420  LOAD(m_info.m_help, edEncoderHelp);
421  LOAD(m_info.m_version, edVersionInfo);
422 
424 }
425 
426 /***************************************************************************/
428 {
429  // get the content of the combo box
430  int index = cbProgram->currentIndex();
431  if (index < Kwave::toInt(ELEMENTS_OF(g_predefined_settings))) {
432  m_settings.m_name = g_predefined_settings[index].m_name;
433  } else {
434  m_settings.m_name = _("*");
435  }
436 
437  // fetch all settings from the dialog content
438  SAVE(m_path, edPath);
439 
440  SAVE(m_input.m_raw_format, edRawFormat);
441  SAVE(m_input.m_byte_order, edByteOrder);
442  SAVE(m_input.m_signed, edSign);
443 
444  SAVE(m_format.m_sample_rate, edSampleRate);
445  SAVE(m_format.m_bits_per_sample, edBitsPerSample);
446  SAVE(m_format.m_channels.m_mono, edMono);
447  SAVE(m_format.m_channels.m_stereo, edStereo);
448 
449  SAVE(m_quality.m_bitrate.m_avg, edBitrateAvg);
450  SAVE(m_quality.m_bitrate.m_min, edBitrateMin);
451  SAVE(m_quality.m_bitrate.m_max, edBitrateMax);
452 
453  SAVE(m_encoding.m_emphasis.m_none, edEmphasisNone);
454  SAVE(m_encoding.m_emphasis.m_50_15ms, edEmphasis5015ms);
455  SAVE(m_encoding.m_emphasis.m_ccit_j17, edEmphasisCCIT_J17);
456 
457  SAVE(m_encoding.m_noise_shaping, edNoiseShaping);
458  SAVE(m_encoding.m_compatibility, edCompatibility);
459 
460  SAVE(m_flags.m_copyright, edCopyright);
461  SAVE(m_flags.m_original, edOriginal);
462  SAVE(m_flags.m_protect, edProtect);
463  SAVE(m_flags.m_prepend, edPrepend);
464  SAVE(m_flags.m_append, edAppend);
465 
466  SAVE(m_info.m_help, edEncoderHelp);
467  SAVE(m_info.m_version, edVersionInfo);
468 
469  m_settings.save();
470 }
471 
472 /***************************************************************************/
474 {
475  if (index < 0) return;
476  if (index >= Kwave::toInt(ELEMENTS_OF(g_predefined_settings))) return;
477 
478  m_settings = g_predefined_settings[index];
479  load();
480 }
481 
482 /***************************************************************************/
484 {
485  int index = cbProgram->currentIndex();
486 
487  for (unsigned i = 0; i < ELEMENTS_OF(g_predefined_settings); i++) {
488  const Kwave::MP3EncoderSettings &settings =
489  g_predefined_settings[i];
490  bool match = true;
491 
492  match &= bool(edPath->text().simplified().contains(settings.m_path,
493  Qt::CaseInsensitive));
494 
495  CHECK(m_input.m_raw_format, edRawFormat);
496  CHECK(m_input.m_byte_order, edByteOrder);
497  CHECK(m_input.m_signed, edSign);
498 
499  CHECK(m_format.m_sample_rate, edSampleRate);
500  CHECK(m_format.m_bits_per_sample, edBitsPerSample);
501  CHECK(m_format.m_channels.m_mono, edMono);
502  CHECK(m_format.m_channels.m_stereo, edStereo);
503 
504  CHECK(m_quality.m_bitrate.m_avg, edBitrateAvg);
505  CHECK(m_quality.m_bitrate.m_min, edBitrateMin);
506  CHECK(m_quality.m_bitrate.m_max, edBitrateMax);
507 
508  CHECK(m_encoding.m_emphasis.m_none, edEmphasisNone);
509  CHECK(m_encoding.m_emphasis.m_50_15ms, edEmphasis5015ms);
510  CHECK(m_encoding.m_emphasis.m_ccit_j17, edEmphasisCCIT_J17);
511 
512  CHECK(m_encoding.m_noise_shaping, edNoiseShaping);
513  CHECK(m_encoding.m_compatibility, edCompatibility);
514 
515  CHECK(m_flags.m_copyright, edCopyright);
516  CHECK(m_flags.m_original, edOriginal);
517  CHECK(m_flags.m_protect, edProtect);
518  CHECK(m_flags.m_prepend, edPrepend);
519  CHECK(m_flags.m_append, edAppend);
520 
521  CHECK(m_info.m_help, edEncoderHelp);
522  CHECK(m_info.m_version, edVersionInfo);
523 
524  if (match) {
525  // found a match against known preset
526  if (Kwave::toInt(i) != index) {
527  cbProgram->setCurrentIndex(i);
529  }
530  return;
531  }
532  }
533 
534  // fallback: "user defined"
535  cbProgram->setCurrentIndex(ELEMENTS_OF(g_predefined_settings));
537 }
538 
539 /***************************************************************************/
540 void Kwave::MP3EncoderDialog::buttonClicked(QAbstractButton *button)
541 {
542  if (!button || !buttonBox) return;
543  switch (buttonBox->standardButton(button)) {
544  case QDialogButtonBox::Ok:
545  // save settings and accept
546  save();
547  break;
548  case QDialogButtonBox::Reset:
549  // reset to last saved state
550  load();
551  break;
552  case QDialogButtonBox::RestoreDefaults:
553  // reset to default settings == entry #0 in the combo box
554  selectProgram(0);
555  break;
556  default:
557  break;
558  }
559 }
560 
561 /***************************************************************************/
563 {
564  for (unsigned i = 0; i < ELEMENTS_OF(g_predefined_settings); ++i) {
565  QFile f(searchPath(g_predefined_settings[i].m_path));
566  if (f.exists()) {
567  // found it :)
568  cbProgram->setCurrentIndex(i);
569  selectProgram(i);
570  locatePath();
571  return;
572  }
573  }
574 }
575 
576 /***************************************************************************/
578 {
579  const QString prog_orig = edPath->text().simplified();
580  const QString prog = searchPath(prog_orig);
581  if (prog != prog_orig) {
582  edPath->setText(prog);
584  }
585 }
586 
587 /***************************************************************************/
589 {
590  QString mask = _("*");
591 #ifdef EXECUTABLE_SUFFIX
592  mask += QString(EXECUTABLE_SUFFIX);
593 #endif
594  QPointer<Kwave::FileDialog> dlg = new(std::nothrow)
596  _("kfiledialog:///kwave_mp3_encoder"),
598  _(""), this,
599  QUrl::fromLocalFile(_("file:/") + edPath->text().simplified()),
600  mask
601  );
602  if (!dlg) return;
603  dlg->setWindowTitle(i18n("Select MP3 Encoder"));
604  dlg->setDirectory(_("/usr/bin/"));
605  if (dlg->exec() == QDialog::Accepted)
606  edPath->setText(dlg->selectedUrl().toLocalFile());
607  delete dlg;
608 }
609 
610 /***************************************************************************/
612 {
613  const sample_index_t test_length = 128 * 1024; // 128k samples
614  const double sample_rate = 44100.0;
615  const unsigned int bits = 16;
616  const unsigned int tracks = 2;
617 
618  // save all data, so that the encoder can read it
619  save();
620 
621  // us a dummy sink in memory
622  QBuffer dst;
623 
624  // create some dummy audio data (stereo)
625  Kwave::SignalManager manager(this);
626  manager.newSignal(test_length, sample_rate, bits, tracks);
627  Kwave::MetaDataList meta_data = manager.metaData();
628 
629  // add some dummy meta data, to cover all parameters of the encoder
630  Kwave::FileInfo info(meta_data);
631  info.set(Kwave::INF_BITRATE_NOMINAL, QVariant(128000));
632  info.set(Kwave::INF_BITRATE_LOWER, QVariant( 64000));
633  info.set(Kwave::INF_BITRATE_UPPER, QVariant(192000));
634  info.set(Kwave::INF_MPEG_EMPHASIS, QVariant(3));
635  info.set(Kwave::INF_COPYRIGHTED, QVariant(1));
636  info.set(Kwave::INF_ORIGINAL, QVariant(1));
637  meta_data.replace(Kwave::MetaDataList(info));
638 
639  // create a multi track reader
640  QList<unsigned int> track_list;
641  track_list.append(0);
642  track_list.append(1);
643  sample_index_t first = 0;
644  sample_index_t last = test_length - 1;
646  manager, track_list, first, last);
647 
648  // create an encoder
649  MP3Encoder encoder;
650 
651  // pass the data through the encoder
652  bool succeeded = encoder.encode(this, src, dst, meta_data);
653 
654  // check return code
655  if (succeeded) {
656  KMessageBox::information(this, i18n(
657  "Congratulation, the test was successful!"));
658  } // else: the plugin has already shown an error message
659 }
660 
661 /***************************************************************************/
663 {
664  // show complete help
665  QString program = edPath->text().simplified();
666  QString param = QString(edEncoderHelp->text()).simplified();
667 
668  QString text = callWithParam(program, param);
669 
670  KMessageBox::information(this, text);
671 }
672 
673 /***************************************************************************/
674 QString Kwave::MP3EncoderDialog::callWithParam(const QString &path,
675  const QString &param)
676 {
677  QStringList params(param);
678 
679  // set hourglass cursor
680  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
681 
682  QProcess process;
683  process.setProcessChannelMode(QProcess::MergedChannels);
684  process.start(path, params);
685  process.waitForStarted();
686  if (process.state() != QProcess::NotRunning) process.waitForFinished();
687 
688  QString text = QString::fromLocal8Bit(process.readAllStandardOutput());
689  qDebug("stdout output: %s", DBG(text));
690 
691  // remove hourglass
692  QApplication::restoreOverrideCursor();
693 
694  return text;
695 }
696 
697 /***************************************************************************/
698 QString Kwave::MP3EncoderDialog::encoderVersion(const QString &path,
699  const QString &param)
700 {
701  QString text = callWithParam(path, param);
702 
703  QStringList lines = text.split(QLatin1Char('\n'));
704 
705  // take the first non-zero line
706  while (lines.count() && !lines.first().simplified().length())
707  lines.removeFirst();
708 
709  return (!lines.isEmpty()) ? lines.first().simplified() : QString();
710 }
711 
712 /***************************************************************************/
713 QString Kwave::MP3EncoderDialog::searchPath(const QString &program)
714 {
715  const QFile::Permissions executable =
716  (QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther);
717 #ifdef Q_OS_WIN
718  const QLatin1Char separator = QLatin1Char(';');
719 #else
720  const QLatin1Char separator = QLatin1Char(':');
721 #endif
722  QStringList path =
723  _(qgetenv("PATH")).split(separator, QString::SkipEmptyParts);
724 
725  QFileInfo f(program);
726  QString d = f.path();
727  if (d.length()) path.prepend(d);
728 
729  foreach (const QString &dir, path) {
730  QString p = dir;
731  if (!p.endsWith(QDir::separator()))
732  p += QDir::separator();
733  p += f.fileName();
734 
735  QFile file(p);
736  qDebug("testing '%s'", DBG(p));
737  if (file.exists() && (file.permissions() & executable)) {
738  // found it :)
739  return p;
740  }
741  }
742 
743  return program;
744 }
745 
746 /***************************************************************************/
748 {
749  int index = cbProgram->currentIndex();
750  QString title;
751 
752  if (index >= Kwave::toInt(ELEMENTS_OF(g_predefined_settings))) {
753  title = PRESET_NAME_USER_DEFINED;
754  }
755 
756  // detect by using the currently selected path
757  if (!title.length()) {
758  // first try with user defined full path
759  QString name = g_predefined_settings[index].m_name;
760  QString program = QFileInfo(edPath->text().simplified()).filePath();
761  QString param = edVersionInfo->text().simplified();
762  QString version = encoderVersion(program, param);
763  if (version.length() >= name.length()) {
764  title = version;
765  } else {
766  // fallback: detect by using list of predefined settings
767  QString p = g_predefined_settings[index].m_info.m_version;
768  program = searchPath(g_predefined_settings[index].m_path);
769  version = encoderVersion(program, p);
770  if (version.length() >= name.length())
771  title = version;
772  }
773  }
774 
775  cbProgram->setItemText(index, title);
776 }
777 
778 //***************************************************************************
780 {
781  KHelpClient::invokeHelp(_("plugin_sect_codec_mp3"));
782 }
783 
784 /***************************************************************************/
785 /***************************************************************************/
Kwave::MP3EncoderSettings m_settings
#define PRESET_NAME_USER_DEFINED
Kwave::MetaDataList & metaData()
#define ELEMENTS_OF(x)
#define EXE_SUFFIX
void newSignal(sample_index_t samples, double rate, unsigned int bits, unsigned int tracks)
#define CONNECT(control)
void setDirectory(const QString &directory)
Definition: FileDialog.cpp:265
quint64 sample_index_t
Definition: Sample.h:28
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
Definition: Connect.cpp:48
void set(FileProperty key, const QVariant &value)
Definition: FileInfo.cpp:363
MP3EncoderDialog(QWidget *parent)
const char name[16]
Definition: memcpy.c:510
#define LOAD(field, control)
int toInt(T x)
Definition: Utils.h:127
#define CHECK(field, control)
const Kwave::MP3EncoderSettings g_predefined_settings[]
virtual void replace(const MetaDataList &list)
#define SAVE(field, control)
QString callWithParam(const QString &path, const QString &param)
#define _(m)
Definition: memcpy.c:66
void buttonClicked(QAbstractButton *button)
#define DBG(qs)
Definition: String.h:55
virtual bool encode(QWidget *widget, Kwave::MultiTrackReader &src, QIODevice &dst, const Kwave::MetaDataList &meta_data)
Definition: MP3Encoder.cpp:265
QString encoderVersion(const QString &path, const QString &param)
QString searchPath(const QString &program)
struct Kwave::MP3EncoderSettings::@8 m_info