diff options
Diffstat (limited to 'plugins/encoder/lame')
-rw-r--r-- | plugins/encoder/lame/Makefile.am | 15 | ||||
-rw-r--r-- | plugins/encoder/lame/base_k3blameencodersettingswidget.ui | 480 | ||||
-rw-r--r-- | plugins/encoder/lame/base_k3bmanualbitratesettingswidget.ui | 273 | ||||
-rw-r--r-- | plugins/encoder/lame/configure.in.bot | 11 | ||||
-rw-r--r-- | plugins/encoder/lame/configure.in.in | 20 | ||||
-rw-r--r-- | plugins/encoder/lame/k3blameencoder.cpp | 627 | ||||
-rw-r--r-- | plugins/encoder/lame/k3blameencoder.h | 88 | ||||
-rw-r--r-- | plugins/encoder/lame/k3blameencoder.plugin | 9 |
8 files changed, 1523 insertions, 0 deletions
diff --git a/plugins/encoder/lame/Makefile.am b/plugins/encoder/lame/Makefile.am new file mode 100644 index 0000000..4a4d61e --- /dev/null +++ b/plugins/encoder/lame/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = -I$(srcdir)/../../../libk3b/core -I$(srcdir)/../../../libk3b/plugin -I$(srcdir)/../../../libk3b/core -I$(srcdir)/../../../libk3bdevice $(all_includes) + +kde_module_LTLIBRARIES = libk3blameencoder.la + +libk3blameencoder_la_SOURCES = base_k3blameencodersettingswidget.ui \ + base_k3bmanualbitratesettingswidget.ui \ + k3blameencoder.cpp + +libk3blameencoder_la_LIBADD = ../../../libk3b/libk3b.la $(LIB_KDECORE) -lmp3lame +libk3blameencoder_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries) + +pluginsdir = $(kde_datadir)/k3b/plugins +plugins_DATA = k3blameencoder.plugin + +METASOURCES = AUTO diff --git a/plugins/encoder/lame/base_k3blameencodersettingswidget.ui b/plugins/encoder/lame/base_k3blameencodersettingswidget.ui new file mode 100644 index 0000000..199895e --- /dev/null +++ b/plugins/encoder/lame/base_k3blameencodersettingswidget.ui @@ -0,0 +1,480 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>base_K3bLameEncoderSettingsWidget</class> +<author>Sebastian Trueg</author> +<widget class="QWidget"> + <property name="name"> + <cstring>Form1</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>337</width> + <height>295</height> + </rect> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QTabWidget"> + <property name="name"> + <cstring>m_mainTab</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Settings</string> + </attribute> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>m_groupVariableBitrate</cstring> + </property> + <property name="title"> + <string>Quality Settings</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>m_radioQualityLevel</cstring> + </property> + <property name="text"> + <string>Preset:</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>m_labelQualityLevel</cstring> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="text"> + <string>textLabel1</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </widget> + <widget class="QFrame"> + <property name="name"> + <cstring>m_qualityLevelFrame</cstring> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="font"> + <font> + <italic>1</italic> + </font> + </property> + <property name="text"> + <string>high quality</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="font"> + <font> + <italic>1</italic> + </font> + </property> + <property name="text"> + <string>small file</string> + </property> + </widget> + <widget class="QSlider" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>m_sliderQuality</cstring> + </property> + <property name="maxValue"> + <number>9</number> + </property> + <property name="pageStep"> + <number>3</number> + </property> + <property name="value"> + <number>3</number> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + </grid> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer9</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout12</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>m_radioManual</cstring> + </property> + <property name="text"> + <string>Manual settings:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>m_labelManualSettings</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="text"> + <string>textLabel2</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>spacer2_2_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>m_buttonManualSettings</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Change Settings...</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Advanced</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>Encoder Quality</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="KIntNumInput"> + <property name="name"> + <cstring>m_spinEncoderQuality</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Choose the noise shaping & psycho acoustic algorithm.</string> + </property> + <property name="whatsThis" stdset="0"> + <string><p>Bitrate is of course the main influence on quality. The higher the bitrate, the higher the quality. But for a given bitrate, we have a choice of algorithms to determine the best scalefactors and huffman encoding (noise shaping). +<p>The quality increases from 0 to 9 while the encoding speed drops. +<p>9 uses the slowest & best possible version of all algorithms. +<p><b>7 is the recommended setting</b> while 4 still produced reasonable quality at good speed. +<p>0 disables almost all algorithms including psy-model resulting in poor quality. +<p><b>This setting has no influence on the size of the resulting file.</b></string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="font"> + <font> + <italic>1</italic> + </font> + </property> + <property name="text"> + <string>fast encoding</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="font"> + <font> + <italic>1</italic> + </font> + </property> + <property name="text"> + <string>high quality</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>m_checkCopyright</cstring> + </property> + <property name="text"> + <string>Mark copyrighted</string> + </property> + <property name="toolTip" stdset="0"> + <string>Mark the encoded file as being copyrighted.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>m_checkOriginal</cstring> + </property> + <property name="text"> + <string>Mark as original</string> + </property> + <property name="toolTip" stdset="0"> + <string>Mark the encoded file as being a copy.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>m_checkISO</cstring> + </property> + <property name="text"> + <string>Strict ISO compliance</string> + </property> + <property name="toolTip" stdset="0"> + <string>Enforce strict ISO compliance</string> + </property> + <property name="whatsThis" stdset="0"> + <string><p>If this option is checked LAME will enforce the 7680 bit limitation on total frame size.<br> +This results in many wasted bits for high bitrate encodings but will ensure strict ISO compatibility. This compatibility might be important for hardware players.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>m_checkError</cstring> + </property> + <property name="text"> + <string>Error protection</string> + </property> + <property name="toolTip" stdset="0"> + <string>Turn on CRC error protection.</string> + </property> + <property name="whatsThis" stdset="0"> + <string><p>If this option is checked a cyclic redundancy check (CRC) code will be added to each frame, allowing transmission errors that could occur on the MP3 stream to be detected; however, it takes 16 bits per frame that would otherwise be used for encoding, thus slightly reducing the sound quality.</string> + </property> + </widget> + </vbox> + </widget> + </vbox> + </widget> + </widget> + </hbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>m_radioManual</sender> + <signal>toggled(bool)</signal> + <receiver>m_buttonManualSettings</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>m_radioQualityLevel</sender> + <signal>toggled(bool)</signal> + <receiver>m_qualityLevelFrame</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>m_radioQualityLevel</sender> + <signal>toggled(bool)</signal> + <receiver>m_labelQualityLevel</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>m_radioManual</sender> + <signal>toggled(bool)</signal> + <receiver>m_labelManualSettings</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/plugins/encoder/lame/base_k3bmanualbitratesettingswidget.ui b/plugins/encoder/lame/base_k3bmanualbitratesettingswidget.ui new file mode 100644 index 0000000..a3bff90 --- /dev/null +++ b/plugins/encoder/lame/base_k3bmanualbitratesettingswidget.ui @@ -0,0 +1,273 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>base_K3bManualBitrateSettingsWidget</class> +<widget class="QWidget"> + <property name="name"> + <cstring>base_K3bManualBitrateSettingsWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>283</width> + <height>298</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buttonGroup2</cstring> + </property> + <property name="title"> + <string>Quality</string> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>m_radioConstantBitrate</cstring> + </property> + <property name="text"> + <string>Constant Bitrate</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KComboBox"> + <property name="name"> + <cstring>m_comboConstantBitrate</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>m_radioVariableBitrate</cstring> + </property> + <property name="text"> + <string>Variable Bitrate</string> + </property> + </widget> + <widget class="QFrame"> + <property name="name"> + <cstring>frame5</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KComboBox" row="2" column="2"> + <property name="name"> + <cstring>m_comboMinimumBitrate</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <spacer row="0" column="0" rowspan="3" colspan="1"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KComboBox" row="0" column="2"> + <property name="name"> + <cstring>m_comboMaximumBitrate</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QCheckBox" row="0" column="1"> + <property name="name"> + <cstring>m_checkBitrateMaximum</cstring> + </property> + <property name="text"> + <string>Maximum bitrate:</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="1"> + <property name="name"> + <cstring>m_checkBitrateMinimum</cstring> + </property> + <property name="text"> + <string>Minimum bitrate:</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="1"> + <property name="name"> + <cstring>m_checkBitrateAverage</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Average bitrate:</string> + </property> + </widget> + <widget class="QSpinBox" row="1" column="2"> + <property name="name"> + <cstring>m_spinAverageBitrate</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> kbps</string> + </property> + <property name="buttonSymbols"> + <enum>UpDownArrows</enum> + </property> + <property name="maxValue"> + <number>310</number> + </property> + <property name="minValue"> + <number>8</number> + </property> + </widget> + </grid> + </widget> + </vbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="title"> + <string>Channel Mode</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KComboBox"> + <item> + <property name="text"> + <string>Stereo</string> + </property> + </item> + <item> + <property name="text"> + <string>Joint Stereo</string> + </property> + </item> + <item> + <property name="text"> + <string>Mono</string> + </property> + </item> + <property name="name"> + <cstring>m_comboMode</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Select the channel mode.</string> + </property> + <property name="whatsThis" stdset="0"> + <string><p>Select the channel mode of the resulting Mp3 file: +<p><b>Stereo</b><br> +In this mode, the encoder makes no use of potential correlations between the two input channels; it can, however, negotiate the bit demand between both channel, i.e. give one channel more bits if the other contains silence or needs fewer bits because of a lower complexity. +<p><b>Joint-Stereo</b><br> +In this mode, the encoder will make use of correlations between both channels. The signal will be matrixed into a sum ("mid"), computed by L+R, and difference ("side") signal, computed by L-R, and more bits are allocated to the mid channel. This will effectively increase the bandwidth if the signal does not have too much stereo separation, thus giving a significant gain in encoding quality. +<p><b>Mono</b><br> +The input will be encoded as a mono signal. If it was a stereo signal, it will be downsampled to mono. The downmix is calculated as the sum of the left and right channel, attenuated by 6 dB.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>m_radioVariableBitrate</sender> + <signal>toggled(bool)</signal> + <receiver>frame5</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>m_radioConstantBitrate</sender> + <signal>toggled(bool)</signal> + <receiver>m_comboConstantBitrate</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>m_checkBitrateMaximum</sender> + <signal>toggled(bool)</signal> + <receiver>m_comboMaximumBitrate</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>m_checkBitrateAverage</sender> + <signal>toggled(bool)</signal> + <receiver>m_spinAverageBitrate</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>m_checkBitrateMinimum</sender> + <signal>toggled(bool)</signal> + <receiver>m_comboMinimumBitrate</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/plugins/encoder/lame/configure.in.bot b/plugins/encoder/lame/configure.in.bot new file mode 100644 index 0000000..5bb35c9 --- /dev/null +++ b/plugins/encoder/lame/configure.in.bot @@ -0,0 +1,11 @@ +echo "" + +if test x$have_lame = xyes; then + echo "K3b - Lame Mp3 encoder plugin: yes" +else + echo "K3b - Lame Mp3 encoder plugin no" +if test "$ac_cv_use_lame" = "yes"; then + echo "K3b - You are missing the Lame headers and libraries." + echo "K3b - The Lame Mp3 encoding plugin won't be compiled." +fi +fi diff --git a/plugins/encoder/lame/configure.in.in b/plugins/encoder/lame/configure.in.in new file mode 100644 index 0000000..f2a5283 --- /dev/null +++ b/plugins/encoder/lame/configure.in.in @@ -0,0 +1,20 @@ +dnl === test for LAME - begin ==== +AC_ARG_WITH( + lame, + AS_HELP_STRING([--without-lame], [build K3b without LAME support (default=no)]), + [ac_cv_use_lame=$withval], + [ac_cv_use_lame=yes] +) + +have_lame=no +if test "$ac_cv_use_lame" = "yes"; then + KDE_CHECK_HEADERS(lame/lame.h, [ + AC_CHECK_LIB(mp3lame, lame_init, [ + have_lame=yes + AC_DEFINE(HAVE_LAME,1,[defined if you have the lame header and lib]) + ], [], $all_libraries -lm) + ]) +fi + +AM_CONDITIONAL(include_LAME, [test x$have_lame = xyes]) +dnl === test for LAME - end ==== diff --git a/plugins/encoder/lame/k3blameencoder.cpp b/plugins/encoder/lame/k3blameencoder.cpp new file mode 100644 index 0000000..089c7d0 --- /dev/null +++ b/plugins/encoder/lame/k3blameencoder.cpp @@ -0,0 +1,627 @@ +/* + * + * $Id: k3blameencoder.cpp 653779 2007-04-14 07:58:51Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include <config.h> + +#include "k3blameencoder.h" + +#include <k3bcore.h> +#include <k3bpluginfactory.h> + +#include <klocale.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kinstance.h> +#include <knuminput.h> +#include <kcombobox.h> +#include <kdialogbase.h> + +#include <qlayout.h> +#include <qcstring.h> +#include <qradiobutton.h> +#include <qcheckbox.h> +#include <qspinbox.h> +#include <qgroupbox.h> +#include <qbuttongroup.h> +#include <qtextcodec.h> +#include <qfile.h> +#include <qslider.h> +#include <qlabel.h> +#include <qpushbutton.h> + +#include <stdio.h> +#include <lame/lame.h> + + +K_EXPORT_COMPONENT_FACTORY( libk3blameencoder, K3bPluginFactory<K3bLameEncoder>( "libk3blameencoder" ) ) + + +static const int s_lame_bitrates[] = { + 32, + 40, + 48, + 56, + 64, + 80, + 96, + 112, + 128, + 160, + 192, + 224, + 256, + 320, + 0 // just used for the loops below +}; + + +static const int s_lame_presets[] = { + 56, // ABR for Voice, Radio, Mono, etc. + 90, // + + V6, // ~115 kbps + V5, // ~130 kbps | Portable - small size + V4, // ~160 kbps + + V3, // ~175 kbps + V2, // ~190 kbps | HiFi - for home or quite listening + V1, // ~210 kbps | + V0, // ~230 kbps + + 320 // ABR 320 neary lossless for archiving (not recommended, use flac instead) +}; + + +static const int s_lame_preset_approx_bitrates[] = { + 56, + 90, + 115, + 130, + 160, + 175, + 190, + 210, + 230, + 320 +}; + + +static const char* s_lame_preset_strings[] = { + I18N_NOOP("Low quality (56 kbps)"), + I18N_NOOP("Low quality (90 kbps)"), + + I18N_NOOP("Portable (average 115 kbps)"), + I18N_NOOP("Portable (average 130 kbps)"), + I18N_NOOP("Portable (average 160 kbps)"), + + I18N_NOOP("HiFi (average 175 kbps)"), + I18N_NOOP("HiFi (average 190 kbps)"), + I18N_NOOP("HiFi (average 210 kbps)"), + I18N_NOOP("HiFi (average 230 kbps)"), + + I18N_NOOP("Archiving (320 kbps)"), +}; + + +static const char* s_lame_mode_strings[] = { + I18N_NOOP("Stereo"), + I18N_NOOP("Joint Stereo"), + I18N_NOOP("Mono") +}; + + + +class K3bLameEncoder::Private +{ +public: + Private() + : flags(0), + fid(0) { + } + + lame_global_flags* flags; + + char buffer[8000]; + + QString filename; + FILE* fid; +}; + + + + +K3bLameEncoder::K3bLameEncoder( QObject* parent, const char* name ) + : K3bAudioEncoder( parent, name ) +{ + d = new Private(); +} + + +K3bLameEncoder::~K3bLameEncoder() +{ + closeFile(); + + delete d; +} + + +bool K3bLameEncoder::openFile( const QString& extension, const QString& filename, const K3b::Msf& length ) +{ + closeFile(); + + d->filename = filename; + d->fid = ::fopen( QFile::encodeName( filename ), "w+" ); + if( d->fid ) + return initEncoder( extension, length ); + else + return false; +} + + +bool K3bLameEncoder::isOpen() const +{ + return ( d->fid != 0 ); +} + + +void K3bLameEncoder::closeFile() +{ + if( isOpen() ) { + finishEncoder(); + ::fclose( d->fid ); + d->fid = 0; + d->filename.truncate(0); + } +} + + +const QString& K3bLameEncoder::filename() const +{ + return d->filename; +} + + +bool K3bLameEncoder::initEncoderInternal( const QString&, const K3b::Msf& length ) +{ + KConfig* c = k3bcore->config(); + c->setGroup( "K3bLameEncoderPlugin" ); + + d->flags = lame_init(); + + if( d->flags == 0 ) { + kdDebug() << "(K3bLameEncoder) lame_init failed." << endl; + return false; + } + + // + // set the format of the input data + // + lame_set_num_samples( d->flags, length.lba()*588 ); + lame_set_in_samplerate( d->flags, 44100 ); + lame_set_num_channels( d->flags, 2 ); + + // + // Lame by default determines the samplerate based on the bitrate + // since we have no option for the user to influence this yet + // we just keep to the good old 44.1 khz + // + lame_set_out_samplerate( d->flags, 44100 ); + + // + // Choose the quality level + // + if( c->readBoolEntry( "Manual Bitrate Settings", false ) ) { + // + // Mode + // + QString mode = c->readEntry( "Mode", "stereo" ); + if( mode == "stereo" ) + lame_set_mode( d->flags, STEREO ); + else if( mode == "joint" ) + lame_set_mode( d->flags, JOINT_STEREO ); + else // mono + lame_set_mode( d->flags, MONO ); + + // + // Variable Bitrate + // + if( c->readBoolEntry( "VBR", false ) ) { + // we use the default algorithm here + lame_set_VBR( d->flags, vbr_default ); + + if( c->readBoolEntry( "Use Maximum Bitrate", false ) ) { + lame_set_VBR_max_bitrate_kbps( d->flags, c->readNumEntry( "Maximum Bitrate", 224 ) ); + } + if( c->readBoolEntry( "Use Minimum Bitrate", false ) ) { + lame_set_VBR_min_bitrate_kbps( d->flags, c->readNumEntry( "Minimum Bitrate", 32 ) ); + + // TODO: lame_set_hard_min + } + if( c->readBoolEntry( "Use Average Bitrate", true ) ) { + lame_set_VBR( d->flags, vbr_abr ); + lame_set_VBR_mean_bitrate_kbps( d->flags, c->readNumEntry( "Average Bitrate", 128 ) ); + } + } + + // + // Constant Bitrate + // + else { + lame_set_VBR( d->flags, vbr_off ); + lame_set_brate( d->flags, c->readNumEntry( "Constant Bitrate", 128 ) ); + } + } + + else { + // + // In lame 0 is the highest quality. Since that is just confusing for the user + // if we call the setting "Quality" we simply invert the value. + // + int q = c->readNumEntry( "Quality Level", 5 ); + if( q < 0 ) q = 0; + if( q > 9 ) q = 9; + + kdDebug() << "(K3bLameEncoder) setting preset encoding value to " << q << endl; + + if ( q < 2 || q > 8 ) { + lame_set_VBR( d->flags, vbr_abr ); + } + else { + lame_set_VBR( d->flags, vbr_default ); + } + lame_set_preset( d->flags, s_lame_presets[q] ); + + if( q < 2 ) + lame_set_mode( d->flags, MONO ); + } + + + // + // file options + // + lame_set_copyright( d->flags, c->readBoolEntry( "Copyright", false ) ); + lame_set_original( d->flags, c->readBoolEntry( "Original", true ) ); + lame_set_strict_ISO( d->flags, c->readBoolEntry( "ISO compliance", false ) ); + lame_set_error_protection( d->flags, c->readBoolEntry( "Error Protection", false ) ); + + + // + // Used Algorithm + // + // default to 2 which is the same as the -h lame option + // THIS HAS NO INFLUENCE ON THE SIZE OF THE FILE! + // + // + // In lame 0 is the highest quality. Since that is just confusing for the user + // if we call the setting "Quality" we simply invert the value. + // + int q = c->readNumEntry( "Encoder Quality", 7 ); + if( q < 0 ) q = 0; + if( q > 9 ) q = 9; + lame_set_quality( d->flags, 9-q ); + + // + // ID3 settings + // + // for now we default to both v1 and v2 tags + id3tag_add_v2( d->flags ); + id3tag_pad_v2( d->flags ); + + return( lame_init_params( d->flags ) != -1 ); +} + + +long K3bLameEncoder::encodeInternal( const char* data, Q_ULONG len ) +{ + // FIXME: we may have to swap data here + int size = lame_encode_buffer_interleaved( d->flags, + (short int*)data, + len/4, + (unsigned char*)d->buffer, + 8000 ); + if( size < 0 ) { + kdDebug() << "(K3bLameEncoder) lame_encode_buffer_interleaved failed." << endl; + return -1; + } + + return ::fwrite( d->buffer, 1, size, d->fid ); +} + + +void K3bLameEncoder::finishEncoderInternal() +{ + int size = lame_encode_flush( d->flags, + (unsigned char*)d->buffer, + 8000 ); + if( size > 0 ) + ::fwrite( d->buffer, 1, size, d->fid ); + + lame_mp3_tags_fid( d->flags, d->fid ); + + lame_close( d->flags ); + d->flags = 0; +} + + +void K3bLameEncoder::setMetaDataInternal( K3bAudioEncoder::MetaDataField f, const QString& value ) +{ + // let's not use UTF-8 here since I don't know how to tell lame... + // FIXME: when we use the codec we only get garbage. Why? + QTextCodec* codec = 0;//QTextCodec::codecForName( "ISO8859-1" ); +// if( !codec ) +// kdDebug() << "(K3bLameEncoder) could not find codec ISO8859-1." << endl; + + switch( f ) { + case META_TRACK_TITLE: + id3tag_set_title( d->flags, codec ? codec->fromUnicode(value).data() : value.latin1() ); + break; + case META_TRACK_ARTIST: + id3tag_set_artist( d->flags, codec ? codec->fromUnicode(value).data() : value.latin1() ); + break; + case META_ALBUM_TITLE: + id3tag_set_album( d->flags, codec ? codec->fromUnicode(value).data() : value.latin1() ); + break; + case META_ALBUM_COMMENT: + id3tag_set_comment( d->flags, codec ? codec->fromUnicode(value).data() : value.latin1() ); + break; + case META_YEAR: + id3tag_set_year( d->flags, codec ? codec->fromUnicode(value).data() : value.latin1() ); + break; + case META_TRACK_NUMBER: + id3tag_set_track( d->flags, codec ? codec->fromUnicode(value).data() : value.latin1() ); + break; + case META_GENRE: + if( id3tag_set_genre( d->flags, codec ? codec->fromUnicode(value).data() : value.latin1() ) ) + kdDebug() << "(K3bLameEncoder) unable to set genre." << endl; + break; + default: + return; + } + + if( lame_init_params( d->flags ) < 0 ) + kdDebug() << "(K3bLameEncoder) lame_init_params failed." << endl; +} + + + + + +K3bLameEncoderSettingsWidget::K3bLameEncoderSettingsWidget( QWidget* parent, const char* name ) + : K3bPluginConfigWidget( parent, name ) +{ + m_w = new base_K3bLameEncoderSettingsWidget( this ); + m_w->m_sliderQuality->setRange( 0, 9 ); + m_w->m_spinEncoderQuality->setRange( 0, 9, true ); + + m_manualSettingsDlg = new KDialogBase( this, 0, true, + i18n("(Lame) Manual Quality Settings") ); + m_brW = new base_K3bManualBitrateSettingsWidget( m_manualSettingsDlg ); + m_manualSettingsDlg->setMainWidget( m_brW ); + + for( int i = 0; s_lame_bitrates[i]; ++i ) + m_brW->m_comboMaximumBitrate->insertItem( i18n("%1 kbps" ).arg(s_lame_bitrates[i]) ); + + for( int i = 0; s_lame_bitrates[i]; ++i ) + m_brW->m_comboMinimumBitrate->insertItem( i18n("%1 kbps" ).arg(s_lame_bitrates[i]) ); + + for( int i = 0; s_lame_bitrates[i]; ++i ) + m_brW->m_comboConstantBitrate->insertItem( i18n("%1 kbps" ).arg(s_lame_bitrates[i]) ); + + + QHBoxLayout* lay = new QHBoxLayout( this ); + lay->setMargin( 0 ); + lay->addWidget( m_w ); + + // TODO: add whatsthis help for the quality level. + // QString qualityLevelWhatsThis = i18n("<p>"); + + connect( m_w->m_buttonManualSettings, SIGNAL(clicked()), + this, SLOT(slotShowManualSettings()) ); + connect( m_w->m_sliderQuality, SIGNAL(valueChanged(int)), + this, SLOT(slotQualityLevelChanged(int)) ); + + updateManualSettingsLabel(); + slotQualityLevelChanged( 5 ); +} + + +K3bLameEncoderSettingsWidget::~K3bLameEncoderSettingsWidget() +{ +} + + +void K3bLameEncoderSettingsWidget::slotShowManualSettings() +{ + // save current settings for proper cancellation + bool constant = m_brW->m_radioConstantBitrate->isChecked(); + int constBitrate = m_brW->m_comboConstantBitrate->currentItem(); + int max = m_brW->m_comboMaximumBitrate->currentItem(); + int min = m_brW->m_comboMinimumBitrate->currentItem(); + int av = m_brW->m_spinAverageBitrate->value(); + int mode = m_brW->m_comboMode->currentItem(); + + if( m_manualSettingsDlg->exec() == QDialog::Rejected ) { + m_brW->m_radioConstantBitrate->setChecked( constant ); + m_brW->m_comboConstantBitrate->setCurrentItem( constBitrate ); + m_brW->m_comboMaximumBitrate->setCurrentItem( max ); + m_brW->m_comboMinimumBitrate->setCurrentItem( min ); + m_brW->m_spinAverageBitrate->setValue( av ); + m_brW->m_comboMode->setCurrentItem( mode ); + } + else + updateManualSettingsLabel(); +} + + +void K3bLameEncoderSettingsWidget::updateManualSettingsLabel() +{ + if( m_brW->m_radioConstantBitrate->isChecked() ) + m_w->m_labelManualSettings->setText( i18n("Constant Bitrate: %1 kbps (%2)") + .arg(s_lame_bitrates[m_brW->m_comboConstantBitrate->currentItem()]) + .arg(i18n(s_lame_mode_strings[m_brW->m_comboMode->currentItem()])) ); + else + m_w->m_labelManualSettings->setText( i18n("Variable Bitrate (%1)") + .arg(i18n(s_lame_mode_strings[m_brW->m_comboMode->currentItem()])) ); +} + + +void K3bLameEncoderSettingsWidget::slotQualityLevelChanged( int val ) +{ + m_w->m_labelQualityLevel->setText( i18n(s_lame_preset_strings[val]) ); +} + + +void K3bLameEncoderSettingsWidget::loadConfig() +{ + KConfig* c = k3bcore->config(); + c->setGroup( "K3bLameEncoderPlugin" ); + + QString mode = c->readEntry( "Mode", "stereo" ); + if( mode == "stereo" ) + m_brW->m_comboMode->setCurrentItem( 0 ); + else if( mode == "joint" ) + m_brW->m_comboMode->setCurrentItem( 1 ); + else // mono + m_brW->m_comboMode->setCurrentItem( 2 ); + + bool manual = c->readBoolEntry( "Manual Bitrate Settings", false ); + if( manual ) + m_w->m_radioManual->setChecked(true); + else + m_w->m_radioQualityLevel->setChecked(true); + + if( c->readBoolEntry( "VBR", false ) ) + m_brW->m_radioVariableBitrate->setChecked( true ); + else + m_brW->m_radioConstantBitrate->setChecked( true ); + + m_brW->m_comboConstantBitrate->setCurrentItem( i18n("%1 kbps").arg(c->readNumEntry( "Constant Bitrate", 128 )) ); + m_brW->m_comboMaximumBitrate->setCurrentItem( i18n("%1 kbps").arg(c->readNumEntry( "Maximum Bitrate", 224 )) ); + m_brW->m_comboMinimumBitrate->setCurrentItem( i18n("%1 kbps").arg(c->readNumEntry( "Minimum Bitrate", 32 )) ); + m_brW->m_spinAverageBitrate->setValue( c->readNumEntry( "Average Bitrate", 128) ); + + m_brW->m_checkBitrateMaximum->setChecked( c->readBoolEntry( "Use Maximum Bitrate", false ) ); + m_brW->m_checkBitrateMinimum->setChecked( c->readBoolEntry( "Use Minimum Bitrate", false ) ); + m_brW->m_checkBitrateAverage->setChecked( c->readBoolEntry( "Use Average Bitrate", true ) ); + + m_w->m_sliderQuality->setValue( c->readNumEntry( "Quality Level", 5 ) ); + + m_w->m_checkCopyright->setChecked( c->readBoolEntry( "Copyright", false ) ); + m_w->m_checkOriginal->setChecked( c->readBoolEntry( "Original", true ) ); + m_w->m_checkISO->setChecked( c->readBoolEntry( "ISO compliance", false ) ); + m_w->m_checkError->setChecked( c->readBoolEntry( "Error Protection", false ) ); + + // default to 2 which is the same as the -h lame option + m_w->m_spinEncoderQuality->setValue( c->readNumEntry( "Encoder Quality", 7 ) ); + + updateManualSettingsLabel(); +} + + +void K3bLameEncoderSettingsWidget::saveConfig() +{ + KConfig* c = k3bcore->config(); + c->setGroup( "K3bLameEncoderPlugin" ); + + QString mode; + switch( m_brW->m_comboMode->currentItem() ) { + case 0: + mode = "stereo"; + break; + case 1: + mode = "joint"; + break; + case 2: + mode = "mono"; + break; + } + c->writeEntry( "Mode", mode ); + + c->writeEntry( "Manual Bitrate Settings", m_w->m_radioManual->isChecked() ); + + c->writeEntry( "VBR", !m_brW->m_radioConstantBitrate->isChecked() ); + c->writeEntry( "Constant Bitrate", m_brW->m_comboConstantBitrate->currentText().left(3).toInt() ); + c->writeEntry( "Maximum Bitrate", m_brW->m_comboMaximumBitrate->currentText().left(3).toInt() ); + c->writeEntry( "Minimum Bitrate", m_brW->m_comboMinimumBitrate->currentText().left(3).toInt() ); + c->writeEntry( "Average Bitrate", m_brW->m_spinAverageBitrate->value() ); + + c->writeEntry( "Use Maximum Bitrate", m_brW->m_checkBitrateMaximum->isChecked() ); + c->writeEntry( "Use Minimum Bitrate", m_brW->m_checkBitrateMinimum->isChecked() ); + c->writeEntry( "Use Average Bitrate", m_brW->m_checkBitrateAverage->isChecked() ); + + c->writeEntry( "Quality Level", m_w->m_sliderQuality->value() ); + + c->writeEntry( "Copyright", m_w->m_checkCopyright->isChecked() ); + c->writeEntry( "Original", m_w->m_checkOriginal->isChecked() ); + c->writeEntry( "ISO compliance", m_w->m_checkISO->isChecked() ); + c->writeEntry( "Error Protection", m_w->m_checkError->isChecked() ); + + // default to 2 which is the same as the -h lame option + c->writeEntry( "Encoder Quality", m_w->m_spinEncoderQuality->value() ); +} + + + +QStringList K3bLameEncoder::extensions() const +{ + return QStringList( "mp3" ); +} + + +QString K3bLameEncoder::fileTypeComment( const QString& ) const +{ + return "MPEG1 Layer III (mp3)"; +} + + +long long K3bLameEncoder::fileSize( const QString&, const K3b::Msf& msf ) const +{ + KConfig* c = k3bcore->config(); + c->setGroup( "K3bLameEncoderPlugin" ); + int bitrate = 0; + if( c->readBoolEntry( "Manual Bitrate Settings", false ) ) { + if( c->readBoolEntry( "VBR", false ) ) { + if( c->readBoolEntry( "Use Maximum Bitrate", false ) ) + bitrate = c->readNumEntry( "Maximum Bitrate", 224 ); + if( c->readBoolEntry( "Use Minimum Bitrate", false ) ) + bitrate = ( bitrate > 0 + ? (bitrate - c->readNumEntry( "Minimum Bitrate", 32 )) / 2 + : c->readNumEntry( "Minimum Bitrate", 32 ) ); + if( c->readBoolEntry( "Use Average Bitrate", true ) ) + bitrate = c->readNumEntry( "Average Bitrate", 128 ); + } + else { + bitrate = c->readNumEntry( "Constant Bitrate", 128 ); + } + } + else { + int q = c->readNumEntry( "Quality Level", 5 ); + if( q < 0 ) q = 0; + if( q > 9 ) q = 9; + bitrate = s_lame_preset_approx_bitrates[q]; + } + + return (msf.totalFrames()/75 * bitrate * 1000)/8; +} + + +K3bPluginConfigWidget* K3bLameEncoder::createConfigWidget( QWidget* parent, + const char* name ) const +{ + return new K3bLameEncoderSettingsWidget( parent, name ); +} + + +#include "k3blameencoder.moc" diff --git a/plugins/encoder/lame/k3blameencoder.h b/plugins/encoder/lame/k3blameencoder.h new file mode 100644 index 0000000..424ea64 --- /dev/null +++ b/plugins/encoder/lame/k3blameencoder.h @@ -0,0 +1,88 @@ +/* + * + * $Id: k3blameencoder.h 619556 2007-01-03 17:38:12Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#ifndef _K3B_LAME_ENCODER_H_ +#define _K3B_LAME_ENCODER_H_ + + +#include <k3baudioencoder.h> +#include <k3bpluginconfigwidget.h> + +#include "base_k3blameencodersettingswidget.h" +#include "base_k3bmanualbitratesettingswidget.h" + + +class KDialogBase; + + +class K3bLameEncoder : public K3bAudioEncoder +{ + Q_OBJECT + + public: + K3bLameEncoder( QObject* parent = 0, const char* name = 0 ); + ~K3bLameEncoder(); + + bool openFile( const QString& extension, const QString& filename, const K3b::Msf& length ); + bool isOpen() const; + void closeFile(); + const QString& filename() const; + + QStringList extensions() const; + + QString fileTypeComment( const QString& ) const; + + long long fileSize( const QString&, const K3b::Msf& msf ) const; + + int pluginSystemVersion() const { return 3; } + + K3bPluginConfigWidget* createConfigWidget( QWidget* parent = 0, + const char* name = 0 ) const; + + private: + void finishEncoderInternal(); + bool initEncoderInternal( const QString& extension, const K3b::Msf& length ); + long encodeInternal( const char* data, Q_ULONG len ); + void setMetaDataInternal( MetaDataField, const QString& ); + + class Private; + Private* d; +}; + + +class K3bLameEncoderSettingsWidget : public K3bPluginConfigWidget +{ + Q_OBJECT + + public: + K3bLameEncoderSettingsWidget( QWidget* parent = 0, const char* name = 0 ); + ~K3bLameEncoderSettingsWidget(); + + public slots: + void loadConfig(); + void saveConfig(); + + private slots: + void slotQualityLevelChanged( int val ); + void slotShowManualSettings(); + void updateManualSettingsLabel(); + + private: + base_K3bLameEncoderSettingsWidget* m_w; + base_K3bManualBitrateSettingsWidget* m_brW; + KDialogBase* m_manualSettingsDlg; +}; + +#endif diff --git a/plugins/encoder/lame/k3blameencoder.plugin b/plugins/encoder/lame/k3blameencoder.plugin new file mode 100644 index 0000000..432bc58 --- /dev/null +++ b/plugins/encoder/lame/k3blameencoder.plugin @@ -0,0 +1,9 @@ +[K3b Plugin] +Lib=libk3blameencoder +Group=AudioEncoder +Name=K3b Lame Mp3 Encoder +Author=Sebastian Trueg +Version=3.0 +Comment=Encoding module to encode MPEG1 Layer III (mp3) files +License=GPL |