diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | e2de64d6f1beb9e492daf5b886e19933c1fa41dd (patch) | |
tree | 9047cf9e6b5c43878d5bf82660adae77ceee097a /kioslave/audiocd/plugins | |
download | tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.tar.gz tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kioslave/audiocd/plugins')
25 files changed, 3480 insertions, 0 deletions
diff --git a/kioslave/audiocd/plugins/Makefile.am b/kioslave/audiocd/plugins/Makefile.am new file mode 100644 index 00000000..2dd4589c --- /dev/null +++ b/kioslave/audiocd/plugins/Makefile.am @@ -0,0 +1,21 @@ +#if HAVE_VORBIS +#AUDIOCD_PLUGINS_SUBDIR=vorbis +#endif + +SUBDIRS = . wav vorbis lame flac + +INCLUDES = -I$(top_srcdir)/libkcddb $(all_includes) + +lib_LTLIBRARIES = libaudiocdplugins.la + +libaudiocdplugins_la_LIBADD = $(LIB_KDECORE) $(top_builddir)/libkcddb/libkcddb.la + +libaudiocdplugins_la_LDFLAGS = $(all_libraries) -version-info 1:0:0 -no-undefined + +libaudiocdplugins_la_SOURCES = audiocdencoder.cpp + +include_HEADERS = audiocdencoder.h + +messages: + $(XGETTEXT) *.cpp -o $(podir)/kio_audiocd.pot + diff --git a/kioslave/audiocd/plugins/audiocdencoder.cpp b/kioslave/audiocd/plugins/audiocdencoder.cpp new file mode 100644 index 00000000..2a18322a --- /dev/null +++ b/kioslave/audiocd/plugins/audiocdencoder.cpp @@ -0,0 +1,95 @@ +/* + Copyright (C) 2004, 2005 Benjamin Meyer <ben at meyerhome dot net> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include <audiocdencoder.h> +#include <klibloader.h> +#include <kdebug.h> +#include <qdir.h> +#include <qregexp.h> +#include <kstandarddirs.h> + +/** + * Attempt to load a plugin and see if it has the symbol create_audiocd_encoders. + * @param libFileName file to try to load. + * @returns pointer to the symbol or NULL + */ +void *loadPlugin(const QString &libFileName) +{ +#ifdef DEBUG + kdDebug(7117) << "Trying to load library. File: \"" << libFileName.latin1() << "\"." << endl; +#endif + KLibLoader *loader = KLibLoader::self(); + if (!loader) + return NULL; +#ifdef DEBUG + kdDebug(7117) << "We have a loader. File: \"" << libFileName.latin1() << "\"." << endl; +#endif + KLibrary *lib = loader->library(libFileName.latin1()); + if (!lib) + return NULL; +#ifdef DEBUG + kdDebug(7117) << "We have a library. File: \"" << libFileName.latin1() << "\"." << endl; +#endif + void *cplugin = lib->symbol("create_audiocd_encoders"); + if (!cplugin) + return NULL; +#ifdef DEBUG + kdDebug(7117) << "We have a plugin. File: \"" << libFileName.latin1() << "\"." << endl; +#endif + return cplugin; +} + +/** + * There might be a "better" way of doing this, but I don't know it, + * but I do know that this does work. :) Feel free to improve the loading system, + * there isn't much code anyway. + */ +void AudioCDEncoder::findAllPlugins(KIO::SlaveBase *slave, QPtrList<AudioCDEncoder> &encoders){ + QString foundEncoders; + + KStandardDirs standardDirs; + QStringList dirs = standardDirs.findDirs("module", ""); + for (QStringList::Iterator it = dirs.begin(); it != dirs.end(); ++it) { + QDir dir(*it); + if (!dir.exists()) { + kdDebug(7117) << "Directory given by KStandardDirs: " << dir.path() << " doesn't exists!" << endl; + continue; + } + dir.setFilter(QDir::Files | QDir::Hidden); + + QStringList list = dir.entryList( "libaudiocd_encoder_*.so"); + kdDebug() << "list " << list << endl; + for (QStringList::ConstIterator it2 = list.begin(); it2 != list.end(); ++it2) + { + QString fileName = *it2; + kdDebug() << fileName << endl; + if (foundEncoders.contains(fileName)) { + kdDebug(7117) << "Warning, encoder has been found twice!" << endl; + continue; + } + foundEncoders.append(fileName); + fileName = fileName.mid(0, fileName.find('.')); + void *function = loadPlugin(fileName); + if(function){ + void (*functionPointer)(KIO::SlaveBase *, QPtrList<AudioCDEncoder> &) = (void (*)(KIO::SlaveBase *slave, QPtrList<AudioCDEncoder> &encoders)) function; + functionPointer(slave, encoders); + } + } + } +} + diff --git a/kioslave/audiocd/plugins/audiocdencoder.h b/kioslave/audiocd/plugins/audiocdencoder.h new file mode 100644 index 00000000..089be080 --- /dev/null +++ b/kioslave/audiocd/plugins/audiocdencoder.h @@ -0,0 +1,145 @@ +/* + Copyright (C) 2004, 2005 Benjamin Meyer <ben at meyerhome dot net> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef AUDIOCD_ENCODER_H +#define AUDIOCD_ENCODER_H + +#include <sys/types.h> +#include <kio/slavebase.h> +#include <cdinfo.h> + +class KConfigSkeleton; +using namespace KCDDB; + +class AudioCDEncoder { + +public: + /** + * Constructor. + * @param slave parent that this classes can use to call data() with + * when finished encoding bits. + */ + explicit AudioCDEncoder(KIO::SlaveBase *slave) : ioslave(slave) {}; + + /** + * Deconstructor. + */ + virtual ~AudioCDEncoder(){}; + + /** + * Initiallizes the decoder, loading libraries, etc. Encoders + * that don't return true will will deleted and not used. + * @returns false if unable to initialize the encoder. + */ + virtual bool init() = 0; + + /** + * The encoder should read in its config data here. + */ + virtual void loadSettings() = 0; + + /** + * Helper function to determine the end size of a + * encoded file. + * @param time_secs the lengh of the audio track in seconds. + * @returns the size of a file if it is time_secs in length. + */ + virtual unsigned long size(long time_secs) const = 0; + + /** + * @returns the generic user string type/name of this encoder + * Examples: "MP3", "Ogg Vorbis", "Wav", "FID Level 2", etc + */ + virtual QString type() const = 0; + + /** + * @returns the mime type for the files this encoder produces. + * Example: "audio/x-wav" + */ + virtual const char * mimeType() const = 0; + + /** + * @returns the file type for the files this encoder produces. + * Used in naming of the file for example foo.mp3 + * Examples: "mp3", "ogg", "wav" + */ + virtual const char * fileType() const = 0; + + /** + * Before the read functions are called this is + * called to allow the encoders to store the cddb + * information if they want to so it can be inserted + * where neccessary (start, middle, end, or combos etc). + */ + virtual void fillSongInfo( KCDDB::CDInfo info, int track, const QString &comment ) = 0; + + /** + * Perform any initial file creation necessary for a new song (that + * has just been sent via fillSongInfo()) + * @param size - the total binary size of the end file (via size()). + * @return size of the data that was created by this function. + */ + virtual long readInit(long size) = 0; + + /** + * Passes a little bit of cd data to be encoded + * This function is most likly called many many times. + * @param buf pointer to the audio that has been read in so far + * @param frames the number of frames of audio that are in buf + * @return size of the data that was created by this function, -1 on error. + */ + virtual long read(int16_t * buf, int frames) = 0; + + /** + * Perform any final file creation/padding that is necessary + * @return size of the data that was created by this function. + */ + virtual long readCleanup() = 0; + + /** + * Returns a configure widget for the encoder + */ + virtual QWidget* getConfigureWidget(KConfigSkeleton** manager) const + { Q_UNUSED(manager); return NULL; }; + + /** + * Returns the last error message; called when e.g. read() returns -1. + */ + virtual QString lastErrorMessage() const { return QString::null; } + + /** + * Helper function to load all of the AudioCD Encoders from libraries. + * Uses KStandardDirs to find where libraries could be, opens all of the ones + * that we might own audiocd_encoder_* and then uses the symbol + * create_audiocd_encoders to obtain the encoders from that library. + * @param slave ioslave needed if the plugin is going to be used to encode something. + * @param encoders container for new encoders. + */ + static void findAllPlugins(KIO::SlaveBase *slave, QPtrList<AudioCDEncoder> &encoders); + +protected: + /** + * Pointer to the ioslave that is running this encoder. + * Used (only?) for the data() function to pass back encoded data. + */ + KIO::SlaveBase *ioslave; + +}; + +#endif // AUDIOCD_ENCODER_H + diff --git a/kioslave/audiocd/plugins/flac/Makefile.am b/kioslave/audiocd/plugins/flac/Makefile.am new file mode 100644 index 00000000..4e693c53 --- /dev/null +++ b/kioslave/audiocd/plugins/flac/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = -I$(top_srcdir)/libkcddb -I$(srcdir)/.. $(all_includes) + +kde_module_LTLIBRARIES = libaudiocd_encoder_flac.la + +libaudiocd_encoder_flac_la_SOURCES = encoderflac.cpp + +libaudiocd_encoder_flac_la_LIBADD = $(LIBFLAC) $(LIB_KIO) ../libaudiocdplugins.la + +libaudiocd_encoder_flac_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries) + +pluginsdir = $(kde_datadir)/audiocd/plugins + +METASOURCES = AUTO diff --git a/kioslave/audiocd/plugins/flac/encoderflac.cpp b/kioslave/audiocd/plugins/flac/encoderflac.cpp new file mode 100644 index 00000000..ece58708 --- /dev/null +++ b/kioslave/audiocd/plugins/flac/encoderflac.cpp @@ -0,0 +1,197 @@ +/* + Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com> + Copyright (C) 2005 Benjamin Meyer <ben at meyerhome dot net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "encoderflac.h" + +#ifdef HAVE_LIBFLAC + +#include <FLAC/format.h> +#include <FLAC/metadata.h> +#include <FLAC/stream_encoder.h> + +#include <kconfig.h> +#include <kdebug.h> + + +extern "C" +{ + KDE_EXPORT void create_audiocd_encoders(KIO::SlaveBase *slave, QPtrList<AudioCDEncoder> &encoders) + { + encoders.append(new EncoderFLAC(slave)); + } +} + +class EncoderFLAC::Private { + +public: + FLAC__StreamEncoder *encoder; + FLAC__StreamMetadata** metadata; + KIO::SlaveBase* ioslave; + unsigned long data; +}; + +static FLAC__StreamEncoderWriteStatus WriteCallback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) +{ + EncoderFLAC::Private *d = (EncoderFLAC::Private*)client_data; + + d->data += bytes; + + QByteArray output; + + if (bytes) { + output.setRawData((const char*)buffer, bytes); + d->ioslave->data(output); + output.resetRawData((const char*)buffer, bytes); + } + + return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; +} + +static void MetadataCallback (const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data) +{ + // We do not have seekable writeback so we just discard the updated metadata + +} + +/* +static FLAC__SeekableStreamEncoderSeekStatus SeekCallback(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) +{} ; */ + + + + +EncoderFLAC::EncoderFLAC(KIO::SlaveBase *slave) : AudioCDEncoder(slave) { + d = new Private(); + d->ioslave = slave; + d->encoder = 0; +} + +EncoderFLAC::~EncoderFLAC() { + if (d->encoder) FLAC__stream_encoder_delete(d->encoder); + delete d; +} + +bool EncoderFLAC::init(){ + d->encoder = FLAC__stream_encoder_new(); + d->metadata = 0; + d->data = 0; + return true; +} + +void EncoderFLAC::loadSettings() { +// config->setGroup("FLAC"); + +} + +// Estimate size to be 5/8 of uncompresed size. +unsigned long EncoderFLAC::size(long time_secs) const { + long uncompressed = (time_secs * (44100*2*2)); + return (uncompressed/8)*5 + 1000; +} + +long EncoderFLAC::readInit(long size) { + kdDebug(7117) << "EncoderFLAC::readInit() called"<< endl; + d->data = 0; + FLAC__stream_encoder_set_write_callback(d->encoder, WriteCallback); + FLAC__stream_encoder_set_metadata_callback(d->encoder, MetadataCallback); + FLAC__stream_encoder_set_client_data(d->encoder, d); + + // The options match approximely those of flac compression-level-3 + FLAC__stream_encoder_set_do_mid_side_stereo(d->encoder, true); + FLAC__stream_encoder_set_loose_mid_side_stereo(d->encoder, true); // flac -M + FLAC__stream_encoder_set_max_lpc_order(d->encoder, 6); // flac -l6 + FLAC__stream_encoder_set_min_residual_partition_order(d->encoder, 3); + FLAC__stream_encoder_set_max_residual_partition_order(d->encoder, 3); // flac -r3,3 + FLAC__stream_encoder_set_blocksize(d->encoder, 4608); + FLAC__stream_encoder_set_streamable_subset(d->encoder, true); + if (size > 0) + FLAC__stream_encoder_set_total_samples_estimate(d->encoder, size/4); + + FLAC__stream_encoder_init(d->encoder); + return d->data; +} + +long EncoderFLAC::read(int16_t * buf, int frames) +{ + unsigned long olddata = d->data; + FLAC__int32 *buffer = new FLAC__int32[frames*2]; + for(int i=0; i<frames*2;i++) { + buffer[i] = (FLAC__int32)buf[i]; + } + + bool res = FLAC__stream_encoder_process_interleaved (d->encoder, buffer, frames); + delete[] buffer; + return d->data - olddata; +} + +long EncoderFLAC::readCleanup() +{ + FLAC__stream_encoder_finish(d->encoder); +// FLAC__stream_encoder_delete(d->encoder); + if (d->metadata) { + FLAC__metadata_object_delete(d->metadata[0]); + delete[] d->metadata; + d->metadata = 0; + } + return 0; +} + +void EncoderFLAC::fillSongInfo( KCDDB::CDInfo info, int track, const QString &comment ) +{ + d->metadata = new FLAC__StreamMetadata*[1]; + d->metadata[0] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); +// d->metadata[1] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING); +// d->metadata[2] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE) + + typedef QPair<QString, QVariant> Comment; + Comment comments[7] = { Comment("Title", info.trackInfoList[track].get("title")), + Comment("Artist", info.get("artist")), + Comment("Album", info.get("title")), + Comment("Genre", info.get("genre")), + Comment("Tracknumber", QString::number(track+1)), + Comment("Comment", comment), + Comment("Date", QString::null )}; + if (info.get("Year").toInt() > 0) { + QDateTime dt(QDate(info.get("Year").toInt(), 1, 1)); + comments[6] = Comment("Date", dt.toString(Qt::ISODate)); + } + + FLAC__StreamMetadata_VorbisComment_Entry entry; + QString field; + QCString cfield; + int num_comments = 0; + + for(int i=0; i<7; i++) { + if (!comments[i].second.toString().isEmpty()) { + field = comments[i].first+"="+comments[i].second.toString(); + cfield = field.utf8(); + entry.entry = (FLAC__byte*)qstrdup(cfield); + entry.length = cfield.length(); + // Insert in vorbiscomment and assign ownership of pointers to FLAC + FLAC__metadata_object_vorbiscomment_insert_comment(d->metadata[0], num_comments, entry, false); + num_comments++; + } + } + + FLAC__stream_encoder_set_metadata(d->encoder, d->metadata, 1); +} + +#endif // HAVE_LIBFLAC + diff --git a/kioslave/audiocd/plugins/flac/encoderflac.h b/kioslave/audiocd/plugins/flac/encoderflac.h new file mode 100644 index 00000000..f933e809 --- /dev/null +++ b/kioslave/audiocd/plugins/flac/encoderflac.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com> + Copyright (C) 2005 Benjamin Meyer <ben at meyerhome dot net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef ENCODER_FLAC_H +#define ENCODER_FLAC_H + +#include <config.h> + +#ifdef HAVE_LIBFLAC + +#include <audiocdencoder.h> + +/** + * FLAC encoder. + * This encoder is only enabled when HAVE_LIBFLAC is set. + * Check out http://flac.sourceforge.net/ for more information. + */ +class EncoderFLAC : public AudioCDEncoder { + +public: + EncoderFLAC(KIO::SlaveBase *slave); + ~EncoderFLAC(); + + virtual QString type() const { return "FLAC"; }; + virtual bool init(); + virtual void loadSettings(); + virtual unsigned long size(long time_secs) const; + virtual const char * fileType() const { return "flac"; }; + virtual const char * mimeType() const { return "audio/x-flac"; } + virtual void fillSongInfo( KCDDB::CDInfo info, int track, const QString &comment ); + virtual long readInit(long size); + virtual long read(int16_t * buf, int frames); + virtual long readCleanup(); + + class Private; +private: + Private * d; + +}; + +#endif // HAVE_FLAC + +#endif // ENCODER_FLAC_H + diff --git a/kioslave/audiocd/plugins/lame/Makefile.am b/kioslave/audiocd/plugins/lame/Makefile.am new file mode 100644 index 00000000..49ddddd9 --- /dev/null +++ b/kioslave/audiocd/plugins/lame/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = -I$(top_srcdir)/libkcddb -I$(srcdir)/.. $(taglib_includes) $(all_includes) + +kde_kcfg_DATA = audiocd_lame_encoder.kcfg + +kde_module_LTLIBRARIES = libaudiocd_encoder_lame.la + +libaudiocd_encoder_lame_la_SOURCES = audiocd_lame_encoder.kcfgc encoderlame.cpp encoderlameconfig.ui collectingprocess.cpp + +libaudiocd_encoder_lame_la_LIBADD = $(LIB_KIO) ../libaudiocdplugins.la + +libaudiocd_encoder_lame_la_LDFLAGS = -avoid-version -module -no-undefined $(taglib_libs) $(all_libraries) + +pluginsdir = $(kde_datadir)/audiocd/plugins + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/audiocd_encoder_lame.pot diff --git a/kioslave/audiocd/plugins/lame/audiocd_lame_encoder.kcfg b/kioslave/audiocd/plugins/lame/audiocd_lame_encoder.kcfg new file mode 100644 index 00000000..c752fd81 --- /dev/null +++ b/kioslave/audiocd/plugins/lame/audiocd_lame_encoder.kcfg @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 + http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > + <kcfgfile name="kcmaudiocd_encoder_lame_rc"/> + <group name="Lame"> + +<!-- Encoding Method --> + <entry name="bitrate_constant" type="Bool"> + <label>Constant Bitrate</label> + <default>false</default> + </entry> + <entry name="bitrate_variable" type="Bool"> + <label>Variable Bitrate</label> + <default>true</default> + </entry> + + <entry name="stereo" type="Int"> + <label>Stereo Mode</label> + <default>0</default> + </entry> + <entry name="quality" type="Int"> + <label>Quality</label> + <default>-2</default> + </entry> + +<!-- Options --> + <entry name="copyright" type="Bool"> + <label>Copyrighted</label> + <default>false</default> + </entry> + <entry name="original" type="Bool"> + <label>Original</label> + <default>true</default> + </entry> + <entry name="iso" type="Bool"> + <label>ISO Encoding</label> + <default>false</default> + </entry> + <entry name="crc" type="Bool"> + <label>Error protection</label> + <default>false</default> + </entry> + <entry name="id3_tag" type="Bool"> + <label>Write ID3 Tag</label> + <default>true</default> + </entry> + +<!-- Constant Bitrate Settings --> + <entry name="cbr_bitrate" type="Int"> + <label>Constant Bitrate Settings</label> + <default>10</default> + <min>0</min> + <max>13</max> + </entry> + +<!-- Variable Bitrate Settings --> + <entry name="vbr_min_br" type="Bool"> + <label>Minimal bitrate</label> + <default>false</default> + </entry> + <entry name="vbr_min_hard" type="Bool"> + <label>Minimal Value is a hard limit</label> + <default>false</default> + </entry> + <entry name="vbr_max_br" type="Bool"> + <label>Maximal bitrate</label> + <default>false</default> + </entry> + <entry name="vbr_average_br" type="Bool"> + <label>Average bitrate</label> + <default>false</default> + </entry> + <entry name="vbr_xing_tag" type="Bool"> + <label>Write Xing VBR tag</label> + <default>true</default> + </entry> + + <entry name="vbr_min_brate" type="Int"> + <label>Minimal bitrate value</label> + <default>40</default> + <min>0</min> + <max>13</max> + </entry> + <entry name="vbr_max_brate" type="Int"> + <label>Maximal bitrate value</label> + <default>13</default> + <min>0</min> + <max>13</max> + </entry> + <entry name="vbr_mean_brate" type="Int"> + <label>Average bitrate value</label> + <default>10</default> + <min>0</min> + <max>13</max> + </entry> + + +<!-- Filter Settings --> + <entry name="enable_lowpass" type="Bool"> + <label>Lowpass filter cutoff above</label> + <default>false</default> + </entry> + <entry name="lowfilterfreq" type="Int"> + <label>Lowpass filter cutoff above Value</label> + <default>18000</default> + </entry> + + <entry name="enable_highpass" type="Bool"> + <label>Highpass filter cutoff above</label> + <default>false</default> + </entry> + <entry name="highfilterfreq" type="Int"> + <label>Highpass filter cutoff above Value</label> + <default>0</default> + </entry> + + <entry name="set_lpf_width" type="Bool"> + <label>Lowpass filter width</label> + <default>false</default> + </entry> + <entry name="lowfilterwidth" type="Int"> + <label>Lowpass filter width value</label> + <default>900</default> + </entry> + + <entry name="set_hpf_width" type="Bool"> + <label>Highpass filter width</label> + <default>false</default> + </entry> + <entry name="highfilterwidth" type="Int"> + <label>Highpass filter width</label> + <default>0</default> + </entry> + </group> +</kcfg> + diff --git a/kioslave/audiocd/plugins/lame/audiocd_lame_encoder.kcfgc b/kioslave/audiocd/plugins/lame/audiocd_lame_encoder.kcfgc new file mode 100644 index 00000000..b96ee704 --- /dev/null +++ b/kioslave/audiocd/plugins/lame/audiocd_lame_encoder.kcfgc @@ -0,0 +1,4 @@ +# Code generation options for kconfig_compiler +File=audiocd_lame_encoder.kcfg +ClassName=Settings +Singleton=true diff --git a/kioslave/audiocd/plugins/lame/collectingprocess.cpp b/kioslave/audiocd/plugins/lame/collectingprocess.cpp new file mode 100644 index 00000000..b3a13755 --- /dev/null +++ b/kioslave/audiocd/plugins/lame/collectingprocess.cpp @@ -0,0 +1,134 @@ +/* + collectingprocess.cpp + + This file is part of libkdepim. + Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org> + + This library 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. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "collectingprocess.h" + +#include <qvaluelist.h> + +#include <string.h> + +struct CollectingProcess::Private { + Private() : stdoutSize( 0 ), stderrSize( 0 ) + {} + + uint stdoutSize; + QValueList<QByteArray> stdoutBuffer; + uint stderrSize; + QValueList<QByteArray> stderrBuffer; +}; + + +CollectingProcess::CollectingProcess( QObject * parent, const char * name ) + : KProcess( parent, name ) +{ + d = new Private(); +} + +CollectingProcess::~CollectingProcess() { + delete d; d = 0; +} + +bool CollectingProcess::start( RunMode runmode, Communication comm ) { + // prevent duplicate connection + disconnect( this, SIGNAL( receivedStdout( KProcess *, char *, int ) ), + this, SLOT( slotReceivedStdout( KProcess *, char *, int ) ) ); + if ( comm & Stdout ) { + connect( this, SIGNAL( receivedStdout( KProcess *, char *, int ) ), + this, SLOT( slotReceivedStdout( KProcess *, char *, int ) ) ); + } + // prevent duplicate connection + disconnect( this, SIGNAL( receivedStderr( KProcess *, char *, int ) ), + this, SLOT( slotReceivedStderr( KProcess *, char *, int ) ) ); + if ( comm & Stderr ) { + connect( this, SIGNAL( receivedStderr( KProcess *, char *, int ) ), + this, SLOT( slotReceivedStderr( KProcess *, char *, int ) ) ); + } + return KProcess::start( runmode, comm ); +} + +void CollectingProcess::slotReceivedStdout( KProcess *, char *buf, int len ) +{ + QByteArray b; + b.duplicate( buf, len ); + d->stdoutBuffer.append( b ); + d->stdoutSize += len; +} + +void CollectingProcess::slotReceivedStderr( KProcess *, char *buf, int len ) +{ + QByteArray b; + b.duplicate( buf, len ); + d->stderrBuffer.append( b ); + d->stderrSize += len; +} + +QByteArray CollectingProcess::collectedStdout() +{ + if ( d->stdoutSize == 0 ) { + return QByteArray(); + } + + uint offset = 0; + QByteArray b( d->stdoutSize ); + for ( QValueList<QByteArray>::const_iterator it = d->stdoutBuffer.begin(); + it != d->stdoutBuffer.end(); + ++it ) { + memcpy( b.data() + offset, (*it).data(), (*it).size() ); + offset += (*it).size(); + } + d->stdoutBuffer.clear(); + d->stdoutSize = 0; + + return b; +} + +QByteArray CollectingProcess::collectedStderr() +{ + if ( d->stderrSize == 0 ) { + return QByteArray(); + } + + uint offset = 0; + QByteArray b( d->stderrSize ); + for ( QValueList<QByteArray>::const_iterator it = d->stderrBuffer.begin(); + it != d->stderrBuffer.end(); + ++it ) { + memcpy( b.data() + offset, (*it).data(), (*it).size() ); + offset += (*it).size(); + } + d->stderrBuffer.clear(); + d->stderrSize = 0; + + return b; +} + +#include "collectingprocess.moc" diff --git a/kioslave/audiocd/plugins/lame/collectingprocess.h b/kioslave/audiocd/plugins/lame/collectingprocess.h new file mode 100644 index 00000000..7549fee3 --- /dev/null +++ b/kioslave/audiocd/plugins/lame/collectingprocess.h @@ -0,0 +1,72 @@ +/* -*- mode: C++ -*- + collectingprocess.h + + This file is a copy of the collectingprocess.h which is part of kdepim/libkdepim. + Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org> + + This library 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. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __COLLECTINGPROCESS_H__ +#define __COLLECTINGPROCESS_H__ + +#include <kprocess.h> + +/** + * @short An output collecting KProcess class. + * + * This class simplifies the usage of KProcess by collecting all output + * (stdout/stderr) of the process. + * + * @author Ingo Kloecker <kloecker@kde.org> + */ +class CollectingProcess : public KProcess { + Q_OBJECT +public: + CollectingProcess( QObject * parent = 0, const char * name = 0 ); + ~CollectingProcess(); + + /** Starts the process in NotifyOnExit mode and writes in to stdin of + the process. + */ + bool start( RunMode runmode, Communication comm ); + + /** Returns the contents of the stdout buffer and clears it afterwards. */ + QByteArray collectedStdout(); + /** Returns the contents of the stderr buffer and clears it afterwards. */ + QByteArray collectedStderr(); + +private slots: + void slotReceivedStdout( KProcess *, char *, int ); + void slotReceivedStderr( KProcess *, char *, int ); + +private: + class Private; + Private * d; +protected: +}; + +#endif // __COLLECTINGPROCESS_H__ diff --git a/kioslave/audiocd/plugins/lame/encoderlame.cpp b/kioslave/audiocd/plugins/lame/encoderlame.cpp new file mode 100644 index 00000000..a00c60fd --- /dev/null +++ b/kioslave/audiocd/plugins/lame/encoderlame.cpp @@ -0,0 +1,366 @@ +/* + Copyright (C) 2005 Benjamin Meyer <ben at meyerhome dot net> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include <config.h> +#include <endian.h> +#include "encoderlame.h" +#include "encoderlameconfig.h" +#include "audiocd_lame_encoder.h" + +#include <kdebug.h> +#include <qgroupbox.h> +#include <kprocess.h> +#include <kdebug.h> + +#include <kglobal.h> +#include <klocale.h> +#include <kapplication.h> +#include <qfileinfo.h> +#include <ktempfile.h> +#include <kstandarddirs.h> +#include "collectingprocess.h" + +extern "C" +{ + KDE_EXPORT void create_audiocd_encoders(KIO::SlaveBase *slave, QPtrList<AudioCDEncoder> &encoders) { + encoders.append(new EncoderLame(slave)); + } +} + +static int bitrates[] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }; + +class EncoderLame::Private +{ +public: + int bitrate; + bool waitingForWrite; + bool processHasExited; + QString lastErrorMessage; + QStringList genreList; + uint lastSize; + KProcess *currentEncodeProcess; + KTempFile *tempFile; +}; + +EncoderLame::EncoderLame(KIO::SlaveBase *slave) : QObject(), AudioCDEncoder(slave) { + d = new Private(); + d->waitingForWrite = false; + d->processHasExited = false; + d->lastSize = 0; + loadSettings(); +} + +EncoderLame::~EncoderLame(){ + delete d; +} + +QWidget* EncoderLame::getConfigureWidget(KConfigSkeleton** manager) const { + (*manager) = Settings::self(); + KGlobal::locale()->insertCatalogue("audiocd_encoder_lame"); + EncoderLameConfig *config = new EncoderLameConfig(); + config->cbr_settings->hide(); + return config; +} + +bool EncoderLame::init(){ + // Determine if lame is installed on the system or not. + if ( KStandardDirs::findExe( "lame" ).isEmpty() ) + return false; + + // Ask lame for the list of genres it knows; otherwise it barfs when doing + // e.g. lame --tg 'Vocal Jazz' + CollectingProcess proc; + proc << "lame" << "--genre-list"; + proc.start(KProcess::Block, KProcess::Stdout); + + if(proc.exitStatus() != 0) + return false; + + const QByteArray data = proc.collectedStdout(); + QString str; + if ( !data.isEmpty() ) + str = QString::fromLocal8Bit( data, data.size() ); + + d->genreList = QStringList::split( '\n', str ); + // Remove the numbers in front of every genre + for( QStringList::Iterator it = d->genreList.begin(); it != d->genreList.end(); ++it ) { + QString& genre = *it; + uint i = 0; + while ( i < genre.length() && ( genre[i].isSpace() || genre[i].isDigit() ) ) + ++i; + genre = genre.mid( i ); + + } + //kdDebug(7117) << "Available genres:" << d->genreList << endl; + + return true; +} + +void EncoderLame::loadSettings(){ + // Generate the command line arguments for the current settings + args.clear(); + + Settings *settings = Settings::self(); + + int quality = settings->quality(); + if (quality < 0 ) quality = quality *-1; + if (quality > 9) quality = 9; + + int method = settings->bitrate_constant() ? 0 : 1 ; + + if (method == 0) { + // Constant Bitrate Encoding + args.append("-b"); + args.append(QString("%1").arg(bitrates[settings->cbr_bitrate()])); + d->bitrate = bitrates[settings->cbr_bitrate()]; + args.append("-q"); + args.append(QString("%1").arg(quality)); + } + else { + // Variable Bitrate Encoding + if (settings->vbr_average_br()) { + args.append("--abr"); + args.append(QString("%1").arg(bitrates[settings->vbr_mean_brate()])); + d->bitrate = bitrates[settings->vbr_mean_brate()]; + if (settings->vbr_min_br()){ + args.append("-b"); + args.append(QString("%1").arg(bitrates[settings->vbr_min_brate()])); + } + if (settings->vbr_min_hard()) + args.append("-F"); + if (settings->vbr_max_br()){ + args.append("-B"); + args.append(QString("%1").arg(bitrates[settings->vbr_max_brate()])); + } + } else { + d->bitrate = 128; + args.append("-V"); + args.append(QString("%1").arg(quality)); + } + if ( !settings->vbr_xing_tag() ) + args.append("-t"); + } + + args.append("-m"); + switch ( settings->stereo() ) { + case 0: + args.append("s"); + break; + case 1: + args.append("j"); + break; + case 2: + args.append("d"); + break; + case 3: + args.append("m"); + break; + default: + args.append("s"); + break; + } + + if(settings->copyright()) + args.append("-c"); + if(!settings->original()) + args.append("-o"); + if(settings->iso()) + args.append("--strictly-enforce-ISO"); + if(settings->crc()) + args.append("-p"); + + if ( settings->enable_lowpass() ) { + args.append("--lowpass"); + args.append(QString("%1").arg(settings->lowfilterfreq())); + + if (settings->set_lpf_width()){ + args.append("--lowpass-width"); + args.append(QString("%1").arg(settings->lowfilterwidth())); + } + } + + if ( settings->enable_highpass()) { + args.append("--hipass"); + args.append(QString("%1").arg(settings->highfilterfreq())); + + if (settings->set_hpf_width()){ + args.append("--hipass-width"); + args.append(QString("%1").arg(settings->highfilterwidth())); + } + } +} + +unsigned long EncoderLame::size(long time_secs) const { + return (time_secs * d->bitrate * 1000)/8; +} + +long EncoderLame::readInit(long /*size*/){ + // Create KProcess + d->currentEncodeProcess = new KProcess(0); + QString prefix = locateLocal("tmp", ""); + d->tempFile = new KTempFile(prefix, ".mp3"); + d->tempFile->setAutoDelete(true); + d->lastErrorMessage = QString::null; + d->processHasExited = false; + + // -x bitswap + // -r raw/pcm + // -s 44.1 (because it is raw you have to specify this) +#if __BYTE_ORDER == __LITTLE_ENDIAN + *(d->currentEncodeProcess) << "lame" << "--verbose" << "-x" << "-r" << "-s" << "44.1"; +#else + *(d->currentEncodeProcess) << "lame" << "--verbose" << "-r" << "-s" << "44.1"; +#endif + + *(d->currentEncodeProcess) << args; + if(Settings::self()->id3_tag()) + *d->currentEncodeProcess << trackInfo; + + // Read in stdin, output to the temp file + *d->currentEncodeProcess << "-" << d->tempFile->name().latin1(); + + //kdDebug(7117) << d->currentEncodeProcess->args() << endl; + + + connect(d->currentEncodeProcess, SIGNAL(receivedStdout(KProcess *, char *, int)), + this, SLOT(receivedStdout(KProcess *, char *, int))); + connect(d->currentEncodeProcess, SIGNAL(receivedStderr(KProcess *, char *, int)), + this, SLOT(receivedStderr(KProcess *, char *, int))); + connect(d->currentEncodeProcess, SIGNAL(wroteStdin(KProcess *)), + this, SLOT(wroteStdin(KProcess *))); + + connect(d->currentEncodeProcess, SIGNAL(processExited(KProcess *)), + this, SLOT(processExited(KProcess *))); + + // Launch! + d->currentEncodeProcess->start(KProcess::NotifyOnExit, KShellProcess::All); + return 0; +} + +void EncoderLame::processExited ( KProcess *process ){ + kdDebug(7117) << "Lame Encoding process exited with: " << process->exitStatus() << endl; + d->processHasExited = true; +} + +void EncoderLame::receivedStderr( KProcess * /*process*/, char *buffer, int /*buflen*/ ){ + kdDebug(7117) << "Lame stderr: " << buffer << endl; + if ( !d->lastErrorMessage.isEmpty() ) + d->lastErrorMessage += '\t'; + d->lastErrorMessage += QString::fromLocal8Bit( buffer ); +} + +void EncoderLame::receivedStdout( KProcess * /*process*/, char *buffer, int /*length*/ ){ + kdDebug(7117) << "Lame stdout: " << buffer << endl; +} + +void EncoderLame::wroteStdin( KProcess * /*procces*/ ){ + d->waitingForWrite = false; +} + +long EncoderLame::read(int16_t *buf, int frames){ + if(!d->currentEncodeProcess) + return 0; + if (d->processHasExited) + return -1; + + // Pipe the raw data to lame + char * cbuf = reinterpret_cast<char *>(buf); + d->currentEncodeProcess->writeStdin( cbuf, frames*4); + + // We can't return until the buffer has been written + d->waitingForWrite = true; + while(d->waitingForWrite && d->currentEncodeProcess->isRunning()){ + kapp->processEvents(); + usleep(1); + } + + // Determine the file size increase + QFileInfo file(d->tempFile->name()); + uint change = file.size() - d->lastSize; + d->lastSize = file.size(); + return change; +} + +long EncoderLame::readCleanup(){ + if(!d->currentEncodeProcess) + return 0; + + // Let lame tag the first frame of the mp3 + d->currentEncodeProcess->closeStdin(); + while( d->currentEncodeProcess->isRunning()){ + kapp->processEvents(); + usleep(1); + } + + // Now copy the file out of the temp into kio + QFile file( d->tempFile->name() ); + if ( file.open( IO_ReadOnly ) ) { + QByteArray output; + char data[1024]; + while ( !file.atEnd() ) { + uint read = file.readBlock(data, 1024); + output.setRawData(data, read); + ioslave->data(output); + output.resetRawData(data, read); + } + file.close(); + } + + // cleanup the process and temp + delete d->currentEncodeProcess; + delete d->tempFile; + d->lastSize = 0; + + return 0; +} + +void EncoderLame::fillSongInfo( KCDDB::CDInfo info, int track, const QString &comment ){ + trackInfo.clear(); + trackInfo.append("--tt"); + trackInfo.append(info.trackInfoList[track].get("title").toString()); + + trackInfo.append("--ta"); + trackInfo.append(info.get("artist").toString()); + + trackInfo.append("--tl"); + trackInfo.append(info.get("title").toString()); + + trackInfo.append("--ty"); + trackInfo.append(QString("%1").arg(info.get("year").toString())); + + trackInfo.append("--tc"); + trackInfo.append(comment); + + trackInfo.append("--tn"); + trackInfo.append(QString("%1").arg(track+1)); + + const QString genre = info.get( "genre" ).toString(); + if ( d->genreList.find( genre ) != d->genreList.end() ) + { + trackInfo.append("--tg"); + trackInfo.append(genre); + } +} + + +QString EncoderLame::lastErrorMessage() const +{ + return d->lastErrorMessage; +} + +#include "encoderlame.moc" diff --git a/kioslave/audiocd/plugins/lame/encoderlame.h b/kioslave/audiocd/plugins/lame/encoderlame.h new file mode 100644 index 00000000..76aeb59b --- /dev/null +++ b/kioslave/audiocd/plugins/lame/encoderlame.h @@ -0,0 +1,67 @@ +/* + Copyright (C) 2005 Benjamin Meyer <ben at meyerhome dot net> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef ENCODER_LAME_H +#define ENCODER_LAME_H + +#include "audiocdencoder.h" + +class KProcess; + +/** + * MP3 encoder using the LAME encoder. + * Go to http://lame.sourceforge.net/ for lots of information. + */ +class EncoderLame : public QObject, public AudioCDEncoder { + +Q_OBJECT + +public: + EncoderLame(KIO::SlaveBase *slave); + ~EncoderLame(); + + virtual QString type() const { return "MP3"; }; + virtual bool init(); + virtual void loadSettings(); + virtual unsigned long size(long time_secs) const; + virtual const char * fileType() const { return "mp3"; }; + virtual const char * mimeType() const { return "audio/x-mp3"; }; + virtual void fillSongInfo( KCDDB::CDInfo info, int track, const QString &comment ); + virtual long readInit(long size); + virtual long read(int16_t * buf, int frames); + virtual long readCleanup(); + virtual QString lastErrorMessage() const; + + virtual QWidget* getConfigureWidget(KConfigSkeleton** manager) const; + +protected slots: + void wroteStdin(KProcess *proc); + void receivedStdout(KProcess *, char *buffer, int length); + void receivedStderr(KProcess *proc, char *buffer, int buflen); + void processExited(KProcess *proc); + +private: + class Private; + Private * d; + + QStringList args; + QStringList trackInfo; +}; + +#endif // ENCODER_LAME_H + diff --git a/kioslave/audiocd/plugins/lame/encoderlameconfig.ui b/kioslave/audiocd/plugins/lame/encoderlameconfig.ui new file mode 100644 index 00000000..74060353 --- /dev/null +++ b/kioslave/audiocd/plugins/lame/encoderlameconfig.ui @@ -0,0 +1,930 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>EncoderLameConfig</class> +<widget class="QWidget"> + <property name="name"> + <cstring>LameConfig</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>471</width> + <height>598</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox" row="0" column="1"> + <property name="name"> + <cstring>GroupBox1_2</cstring> + </property> + <property name="title"> + <string>Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>kcfg_copyright</cstring> + </property> + <property name="text"> + <string>Cop&yrighted</string> + </property> + <property name="toolTip" stdset="0"> + <string>Mark MP3 file as copyrighted</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Mark MP3 file as copyrighted.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>kcfg_original</cstring> + </property> + <property name="text"> + <string>Origi&nal</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Mark MP3 file as an original</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Mark MP3 file as an original.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>kcfg_iso</cstring> + </property> + <property name="text"> + <string>&ISO encoding</string> + </property> + <property name="toolTip" stdset="0"> + <string>Try to use strict ISO encoding</string> + </property> + <property name="whatsThis" stdset="0"> + <string>This selects the maximal bitrate used for encoding.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>kcfg_crc</cstring> + </property> + <property name="text"> + <string>&Error protection</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>kcfg_id3_tag</cstring> + </property> + <property name="text"> + <string>&Write ID3 tag</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>If checked and if cddb support is available, an id3 tag will be appended</string> + </property> + <property name="whatsThis" stdset="0"> + <string>If checked and if cddb support is available, an id3 tag will be appended</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>buttonGroup1</cstring> + </property> + <property name="title"> + <string>Encoding Method</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>Layout21</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel3_2</cstring> + </property> + <property name="text"> + <string>Low</string> + </property> + </widget> + <widget class="QSlider"> + <property name="name"> + <cstring>kcfg_quality</cstring> + </property> + <property name="minValue"> + <number>-9</number> + </property> + <property name="maxValue"> + <number>0</number> + </property> + <property name="pageStep"> + <number>1</number> + </property> + <property name="value"> + <number>-7</number> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="tickmarks"> + <enum>NoMarks</enum> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2_2</cstring> + </property> + <property name="text"> + <string>High</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel" row="2" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>&Quality:</string> + </property> + <property name="alignment"> + <set>AlignLeft</set> + </property> + <property name="buddy" stdset="0"> + <cstring>kcfg_quality</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="0" rowspan="1" colspan="2"> + <item> + <property name="text"> + <string>Stereo</string> + </property> + </item> + <item> + <property name="text"> + <string>Joint Stereo</string> + </property> + </item> + <item> + <property name="text"> + <string>Dual Channel</string> + </property> + </item> + <item> + <property name="text"> + <string>Mono</string> + </property> + </item> + <property name="name"> + <cstring>kcfg_stereo</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>This option controls whether MP3 files are recorded with one or two channels. Note that choosing <i>"Mono"</i> reduces file size, but also kills the stereo signal.</string> + </property> + </widget> + <widget class="QRadioButton" row="0" column="0"> + <property name="name"> + <cstring>kcfg_bitrate_constant</cstring> + </property> + <property name="text"> + <string>Constant bitrate</string> + </property> + </widget> + <widget class="QRadioButton" row="0" column="1"> + <property name="name"> + <cstring>kcfg_bitrate_variable</cstring> + </property> + <property name="text"> + <string>Variable bitrate</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <spacer row="4" column="0"> + <property name="name"> + <cstring>spacer11</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="QGroupBox" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>vbr_settings</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Variable Bitrate Settings</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox" row="3" column="0"> + <property name="name"> + <cstring>kcfg_vbr_average_br</cstring> + </property> + <property name="text"> + <string>Specify avera&ge bitrate:</string> + </property> + <property name="whatsThis" stdset="0"> + <string>This selects the maximal bitrate used for encoding.</string> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <item> + <property name="text"> + <string>32 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>40 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>48 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>56 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>64 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>80 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>96 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>112 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>128 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>160 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>192 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>224 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>256 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>320 kbs</string> + </property> + </item> + <property name="name"> + <cstring>kcfg_vbr_max_brate</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="currentItem"> + <number>13</number> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>kcfg_vbr_max_br</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Maximal bi&trate:</string> + </property> + <property name="whatsThis" stdset="0"> + <string>This selects the maximal bitrate used for encoding.</string> + </property> + </widget> + <widget class="QCheckBox" row="4" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>kcfg_vbr_xing_tag</cstring> + </property> + <property name="text"> + <string>Write &Xing VBR tag</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>This writes additional information related to VBR as introduced by Xing.</string> + </property> + </widget> + <widget class="QComboBox" row="3" column="1"> + <item> + <property name="text"> + <string>32 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>40 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>48 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>56 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>64 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>80 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>96 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>112 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>128 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>160 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>192 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>224 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>256 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>320 kbs</string> + </property> + </item> + <property name="name"> + <cstring>kcfg_vbr_mean_brate</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="currentItem"> + <number>9</number> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>kcfg_vbr_min_hard</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Minimal &value is a hard limit</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>kcfg_vbr_min_br</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Minimal &bitrate:</string> + </property> + <property name="whatsThis" stdset="0"> + <string>This selects the minimal bitrate used for encoding.</string> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <item> + <property name="text"> + <string>32 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>40 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>48 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>56 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>64 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>80 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>96 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>112 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>128 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>160 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>192 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>224 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>256 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>320 kbs</string> + </property> + </item> + <property name="name"> + <cstring>kcfg_vbr_min_brate</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="currentItem"> + <number>1</number> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>cbr_settings</cstring> + </property> + <property name="title"> + <string>Constant Bitrate Settings</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel4_2</cstring> + </property> + <property name="text"> + <string>Bitrate:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>kcfg_cbr_bitrate</cstring> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>32 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>40 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>48 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>56 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>64 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>80 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>96 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>112 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>128 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>160 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>192 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>224 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>256 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>320 kbs</string> + </property> + </item> + <property name="name"> + <cstring>kcfg_cbr_bitrate</cstring> + </property> + <property name="currentItem"> + <number>9</number> + </property> + <property name="whatsThis" stdset="0"> + <string>The higher the bitrate, the better the quality and the larger the file.</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>GroupBox83_2</cstring> + </property> + <property name="title"> + <string>Filter Settings</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignLeft</set> + </property> + <property name="hAlign" stdset="0"> + </property> + <property name="vAlign" stdset="0"> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>kcfg_enable_lowpass</cstring> + </property> + <property name="text"> + <string>&Lowpass filter cutoff above</string> + </property> + </widget> + <widget class="QSpinBox" row="1" column="0"> + <property name="name"> + <cstring>kcfg_lowfilterfreq</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> Hz</string> + </property> + <property name="maxValue"> + <number>20000</number> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>kcfg_enable_highpass</cstring> + </property> + <property name="text"> + <string>&Highpass filter cutoff below</string> + </property> + </widget> + <widget class="QSpinBox" row="3" column="0"> + <property name="name"> + <cstring>kcfg_highfilterfreq</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> Hz</string> + </property> + <property name="maxValue"> + <number>200</number> + </property> + </widget> + <widget class="QCheckBox" row="0" column="1"> + <property name="name"> + <cstring>kcfg_set_lpf_width</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Low&pass filter width</string> + </property> + </widget> + <widget class="QSpinBox" row="1" column="1"> + <property name="name"> + <cstring>kcfg_lowfilterwidth</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> Hz</string> + </property> + <property name="maxValue"> + <number>5000</number> + </property> + </widget> + <widget class="QCheckBox" row="2" column="1"> + <property name="name"> + <cstring>kcfg_set_hpf_width</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Highpa&ss filter width</string> + </property> + </widget> + <widget class="QSpinBox" row="3" column="1"> + <property name="name"> + <cstring>kcfg_highfilterwidth</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> Hz</string> + </property> + <property name="maxValue"> + <number>50</number> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>kcfg_bitrate_constant</sender> + <signal>toggled(bool)</signal> + <receiver>cbr_settings</receiver> + <slot>setShown(bool)</slot> + </connection> + <connection> + <sender>kcfg_enable_highpass</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_highfilterfreq</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_enable_highpass</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_highfilterwidth</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_enable_lowpass</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_lowfilterfreq</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_enable_lowpass</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_lowfilterwidth</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_enable_highpass</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_set_hpf_width</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_enable_lowpass</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_set_lpf_width</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_vbr_average_br</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_vbr_max_br</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_vbr_max_br</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_vbr_max_brate</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_vbr_average_br</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_vbr_mean_brate</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_vbr_average_br</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_vbr_min_br</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_vbr_min_br</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_vbr_min_brate</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_vbr_min_br</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_vbr_min_hard</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_bitrate_variable</sender> + <signal>toggled(bool)</signal> + <receiver>vbr_settings</receiver> + <slot>setShown(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>kcfg_bitrate_variable</tabstop> + <tabstop>kcfg_stereo</tabstop> + <tabstop>kcfg_quality</tabstop> + <tabstop>kcfg_copyright</tabstop> + <tabstop>kcfg_original</tabstop> + <tabstop>kcfg_iso</tabstop> + <tabstop>kcfg_crc</tabstop> + <tabstop>kcfg_id3_tag</tabstop> + <tabstop>kcfg_cbr_bitrate</tabstop> + <tabstop>kcfg_vbr_min_br</tabstop> + <tabstop>kcfg_vbr_min_hard</tabstop> + <tabstop>kcfg_vbr_max_br</tabstop> + <tabstop>kcfg_vbr_average_br</tabstop> + <tabstop>kcfg_vbr_xing_tag</tabstop> + <tabstop>kcfg_vbr_min_brate</tabstop> + <tabstop>kcfg_vbr_max_brate</tabstop> + <tabstop>kcfg_vbr_mean_brate</tabstop> + <tabstop>kcfg_enable_lowpass</tabstop> + <tabstop>kcfg_lowfilterfreq</tabstop> + <tabstop>kcfg_enable_highpass</tabstop> + <tabstop>kcfg_highfilterfreq</tabstop> + <tabstop>kcfg_set_lpf_width</tabstop> + <tabstop>kcfg_lowfilterwidth</tabstop> + <tabstop>kcfg_set_hpf_width</tabstop> + <tabstop>kcfg_highfilterwidth</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kioslave/audiocd/plugins/vorbis/Makefile.am b/kioslave/audiocd/plugins/vorbis/Makefile.am new file mode 100644 index 00000000..e83240ff --- /dev/null +++ b/kioslave/audiocd/plugins/vorbis/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = -I$(top_srcdir)/libkcddb -I$(srcdir)/.. $(all_includes) + +kde_kcfg_DATA = audiocd_vorbis_encoder.kcfg + +kde_module_LTLIBRARIES = libaudiocd_encoder_vorbis.la + +libaudiocd_encoder_vorbis_la_SOURCES = audiocd_vorbis_encoder.kcfgc encodervorbis.cpp encodervorbisconfig.ui + +libaudiocd_encoder_vorbis_la_LIBADD = $(VORBIS_LIBS) $(VORBISFILE_LIBS) $(VORBISENC_LIBS) $(LIB_KIO) ../libaudiocdplugins.la + +libaudiocd_encoder_vorbis_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries) + +pluginsdir = $(kde_datadir)/audiocd/plugins + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/audiocd_encoder_vorbis.pot diff --git a/kioslave/audiocd/plugins/vorbis/audiocd_vorbis_encoder.kcfg b/kioslave/audiocd/plugins/vorbis/audiocd_vorbis_encoder.kcfg new file mode 100644 index 00000000..53465f6c --- /dev/null +++ b/kioslave/audiocd/plugins/vorbis/audiocd_vorbis_encoder.kcfg @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 + http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > + <kcfgfile name="kcmaudiocd_encoder_vorbis_rc"/> + <group name="Vorbis"> + + <entry name="vorbis_enc_method" type="Int"> + <label>Vorbis Encoding Quality or Bitrate</label> + <default>0</default> + </entry> + + <entry name="set_vorbis_min_br" type="Bool"> + <label>Minimal bitrate specified</label> + <default>false</default> + </entry> + <entry name="set_vorbis_max_br" type="Bool"> + <label>Maximal bitrate specified</label> + <default>false</default> + </entry> + <entry name="set_vorbis_nominal_br" type="Bool"> + <label>Average bitrate specified</label> + <default>true</default> + </entry> + + <entry name="vorbis_comments" type="Bool"> + <label>Add Comments</label> + <default>true</default> + </entry> + <entry name="vorbis_quality" type="Double"> + <label>Quality</label> + <default>3</default> + <min>-1</min> + <max>10</max> + </entry> + + <entry name="vorbis_min_br" type="Int"> + <label>Minimal bitrate</label> + <default>1</default> + <min>0</min> + <max>13</max> + </entry> + + <entry name="vorbis_max_br" type="Int"> + <label>maximal bitrate</label> + <default>13</default> + <min>0</min> + <max>13</max> + </entry> + + <entry name="vorbis_nominal_br" type="Int"> + <label>maximal bitrate</label> + <default>3</default> + <min>0</min> + <max>5</max> + </entry> + +<!-- + <entry name="vorbis_nominal_br" type="Enum"> + <label>maximal bitrate</label> + <default>150</default> + <choices> + <choice name="32"/> + <choice name="40"/> + <choice name="48"/> + <choice name="56"/> + <choice name="64"/> + <choice name="80"/> + <choice name="96"/> + <choice name="112"/> + <choice name="128"/> + <choice name="160"/> + <choice name="192"/> + <choice name="224"/> + <choice name="256"/> + <choice name="350"/> + </choices> + </entry> --> + + + </group> +</kcfg> + diff --git a/kioslave/audiocd/plugins/vorbis/audiocd_vorbis_encoder.kcfgc b/kioslave/audiocd/plugins/vorbis/audiocd_vorbis_encoder.kcfgc new file mode 100644 index 00000000..e213ccbd --- /dev/null +++ b/kioslave/audiocd/plugins/vorbis/audiocd_vorbis_encoder.kcfgc @@ -0,0 +1,4 @@ +# Code generation options for kconfig_compiler +File=audiocd_vorbis_encoder.kcfg +ClassName=Settings +Singleton=true diff --git a/kioslave/audiocd/plugins/vorbis/encodervorbis.cpp b/kioslave/audiocd/plugins/vorbis/encodervorbis.cpp new file mode 100644 index 00000000..01d8b00b --- /dev/null +++ b/kioslave/audiocd/plugins/vorbis/encodervorbis.cpp @@ -0,0 +1,336 @@ +/* + Copyright (C) 2000 Rik Hemsley (rikkus) <rik@kde.org> + Copyright (C) 2000, 2001, 2002 Michael Matz <matz@kde.org> + Copyright (C) 2001 Carsten Duvenhorst <duvenhorst@m2.uni-hannover.de> + Copyright (C) 2001 Adrian Schroeter <adrian@suse.de> + Copyright (C) 2003 Richard Lärkäng <richard@goteborg.utfors.se> + Copyright (C) 2003 Scott Wheeler <wheeler@kde.org> + Copyright (C) 2004, 2005 Benjamin Meyer <ben at meyerhome dot net> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "encodervorbis.h" +#include "audiocd_vorbis_encoder.h" +#include "encodervorbisconfig.h" + +#ifdef HAVE_VORBIS + +#include <vorbis/vorbisenc.h> +#include <time.h> +#include <stdlib.h> +#include <kconfig.h> +#include <knuminput.h> +#include <qgroupbox.h> + +#include <kglobal.h> +#include <klocale.h> + +extern "C" +{ + KDE_EXPORT void create_audiocd_encoders(KIO::SlaveBase *slave, QPtrList<AudioCDEncoder> &encoders) + { + encoders.append(new EncoderVorbis(slave)); + } +} + +// these are the approx. bitrates for the current 5 Vorbis modes +static int vorbis_nominal_bitrates[] = { 128, 160, 192, 256, 350 }; +static int vorbis_bitrates[] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 350 }; + +class EncoderVorbis::Private { + +public: + ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */ + ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ + ogg_packet op; /* one raw packet of data for decode */ + + vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */ + vorbis_comment vc; /* struct that stores all the user comments */ + + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + bool write_vorbis_comments; + long vorbis_bitrate_lower; + long vorbis_bitrate_upper; + long vorbis_bitrate_nominal; + int vorbis_encode_method; + double vorbis_quality; + int vorbis_bitrate; +}; + +EncoderVorbis::EncoderVorbis(KIO::SlaveBase *slave) : AudioCDEncoder(slave) { + d = new Private(); +} + +EncoderVorbis::~EncoderVorbis(){ + delete d; +} + +QWidget* EncoderVorbis::getConfigureWidget(KConfigSkeleton** manager) const { + (*manager) = Settings::self(); + KGlobal::locale()->insertCatalogue("audiocd_encoder_vorbis"); + EncoderVorbisConfig *config = new EncoderVorbisConfig(); + config->kcfg_vorbis_quality->setRange(0.0, 10.0, 0.2, true); + config->vorbis_bitrate_settings->hide(); + return config; +} + +bool EncoderVorbis::init(){ + vorbis_info_init(&d->vi); + vorbis_comment_init(&d->vc); + + vorbis_comment_add_tag + ( + &d->vc, + const_cast<char *>("kde-encoder"), + const_cast<char *>("kio_audiocd") + ); + return true; +} + +void EncoderVorbis::loadSettings(){ + Settings *settings = Settings::self(); + + d->vorbis_encode_method = settings->vorbis_enc_method(); + d->vorbis_quality = settings->vorbis_quality(); + + if ( settings->set_vorbis_min_br()) { + d->vorbis_bitrate_lower = vorbis_bitrates[settings->vorbis_min_br()] * 1000; + } else { + d->vorbis_bitrate_lower = -1; + } + + if ( settings->set_vorbis_max_br() ) { + d->vorbis_bitrate_upper = vorbis_bitrates[settings->vorbis_max_br()] * 1000; + } else { + d->vorbis_bitrate_upper = -1; + } + + // this is such a hack! + if ( d->vorbis_bitrate_upper != -1 && d->vorbis_bitrate_lower != -1 ) { + d->vorbis_bitrate = 104000; // empirically determined ...?! + } else { + d->vorbis_bitrate = 160 * 1000; + } + + if ( settings->set_vorbis_nominal_br() ) { + d->vorbis_bitrate_nominal = vorbis_nominal_bitrates[settings->vorbis_nominal_br()] * 1000; + d->vorbis_bitrate = d->vorbis_bitrate_nominal; + } else { + d->vorbis_bitrate_nominal = -1; + } + + d->write_vorbis_comments = settings->vorbis_comments(); + + // Now that we have read in the settings apply them to the encoder lib + switch (d->vorbis_encode_method) { + case 0: +/* Support very old libvorbis by simply falling through. */ +#if HAVE_VORBIS >= 2 + vorbis_encode_init_vbr(&d->vi, 2, 44100, d->vorbis_quality/10.0); + break; +#endif + case 1: + vorbis_encode_init(&d->vi, 2, 44100, d->vorbis_bitrate_upper, d->vorbis_bitrate_nominal, d->vorbis_bitrate_lower); + break; + } + +} + +long EncoderVorbis::flush_vorbis(void) { + long processed(0); + + while(vorbis_analysis_blockout(&d->vd,&d->vb)==1) { + /* Support ancient libvorbis (< RC3). */ +#if HAVE_VORBIS >= 2 + vorbis_analysis(&d->vb,NULL); + /* Non-ancient case. */ + vorbis_bitrate_addblock(&d->vb); + + while(vorbis_bitrate_flushpacket(&d->vd, &d->op)) { +#else + vorbis_analysis(&d->vb,&d->op); + /* Make a lexical block to place the #ifdef's nearby. */ + if (1) { +#endif + ogg_stream_packetin(&d->os,&d->op); + while(int result=ogg_stream_pageout(&d->os,&d->og)) { + if (!result) break; + + QByteArray output; + + char * oggheader = reinterpret_cast<char *>(d->og.header); + char * oggbody = reinterpret_cast<char *>(d->og.body); + + if (d->og.header_len) { + output.setRawData(oggheader, d->og.header_len); + ioslave->data(output); + output.resetRawData(oggheader, d->og.header_len); + } + + if (d->og.body_len) { + output.setRawData(oggbody, d->og.body_len); + ioslave->data(output); + output.resetRawData(oggbody, d->og.body_len); + } + processed += d->og.header_len + d->og.body_len; + } + } + } + return processed; +} + +unsigned long EncoderVorbis::size(long time_secs) const { + long vorbis_size; + switch (d->vorbis_encode_method) + { + case 0: // quality based encoding + +#if HAVE_VORBIS >= 2 // If really old Vorbis is being used, skip this nicely. + + { + // Estimated numbers based on the Vorbis FAQ: + // http://www.xiph.org/archives/vorbis-faq/200203/0030.html + + static long vorbis_q_bitrate[] = { 60, 74, 86, 106, 120, 152, + 183, 207, 239, 309, 440 }; + long quality = static_cast<long>(d->vorbis_quality); + if (quality < 0 || quality > 10) + quality = 3; + vorbis_size = (time_secs * vorbis_q_bitrate[quality] * 1000) / 8; + + break; + } + +#endif // HAVE_VORBIS >= 2 + + default: // bitrate based encoding + vorbis_size = (time_secs * d->vorbis_bitrate/8); + break; + } + + return vorbis_size; +} + +const char * EncoderVorbis::mimeType() const{ + return "audio/vorbis"; +} + +long EncoderVorbis::readInit(long /*size*/){ + ogg_packet header; + ogg_packet header_comm; + ogg_packet header_code; + + vorbis_analysis_init(&d->vd,&d->vi); + vorbis_block_init(&d->vd,&d->vb); + + srand(time(NULL)); + ogg_stream_init(&d->os,rand()); + + vorbis_analysis_headerout(&d->vd,&d->vc,&header,&header_comm,&header_code); + + ogg_stream_packetin(&d->os,&header); + ogg_stream_packetin(&d->os,&header_comm); + ogg_stream_packetin(&d->os,&header_code); + + while (int result = ogg_stream_flush(&d->os,&d->og)) { + + if (!result) break; + + QByteArray output; + + char * oggheader = reinterpret_cast<char *>(d->og.header); + char * oggbody = reinterpret_cast<char *>(d->og.body); + + if (d->og.header_len) { + output.setRawData(oggheader, d->og.header_len); + ioslave->data(output); + output.resetRawData(oggheader, d->og.header_len); + } + + if (d->og.body_len) { + output.setRawData(oggbody, d->og.body_len); + ioslave->data(output); + output.resetRawData(oggbody, d->og.body_len); + } + } + return 0; +} + +long EncoderVorbis::read(int16_t * buf, int frames){ + int i; + float **buffer=vorbis_analysis_buffer(&d->vd,frames); + + /* uninterleave samples */ + for(i=0;i<frames;i++){ + buffer[0][i]=buf[2*i]/32768.0; + buffer[1][i]=buf[2*i+1]/32768.0; + } + + /* process chunk of data */ + vorbis_analysis_wrote(&d->vd,i); + return flush_vorbis(); +} + +long EncoderVorbis::readCleanup(){ + // send end-of-stream and flush the encoder + vorbis_analysis_wrote(&d->vd,0); + long processed = flush_vorbis(); + ogg_stream_clear(&d->os); + vorbis_block_clear(&d->vb); + vorbis_dsp_clear(&d->vd); + vorbis_info_clear(&d->vi); + return processed; +} + +void EncoderVorbis::fillSongInfo( KCDDB::CDInfo info, int track, const QString &comment ) +{ + if( !d->write_vorbis_comments ) + return; + + typedef QPair<QCString, QVariant> CommentField; + QValueList<CommentField> commentFields; + + commentFields.append(CommentField("title", info.trackInfoList[track].get("title"))); + commentFields.append(CommentField("artist", info.get("artist"))); + commentFields.append(CommentField("album", info.get("title"))); + commentFields.append(CommentField("genre", info.get("genre"))); + commentFields.append(CommentField("tracknumber", QString::number(track+1))); + commentFields.append(CommentField("comment", comment)); + + if (info.get("year").toInt() > 0) { + QDateTime dt(QDate(info.get("year").toInt(), 1, 1)); + commentFields.append(CommentField("date", dt.toString(Qt::ISODate).utf8().data())); + } + + for(QValueListIterator<CommentField> it = commentFields.begin(); it != commentFields.end(); ++it) { + + // if the value is not empty + if(!(*it).second.toString().isEmpty()) { + + char *key = qstrdup((*it).first); + char *value = qstrdup((*it).second.toString().utf8().data()); + + vorbis_comment_add_tag(&d->vc, key, value); + + delete [] key; + delete [] value; + } + } +} + +#endif // HAVE_VORBIS + diff --git a/kioslave/audiocd/plugins/vorbis/encodervorbis.h b/kioslave/audiocd/plugins/vorbis/encodervorbis.h new file mode 100644 index 00000000..28b837ce --- /dev/null +++ b/kioslave/audiocd/plugins/vorbis/encodervorbis.h @@ -0,0 +1,68 @@ +/* + Copyright (C) 2000 Rik Hemsley (rikkus) <rik@kde.org> + Copyright (C) 2000, 2001, 2002 Michael Matz <matz@kde.org> + Copyright (C) 2001 Carsten Duvenhorst <duvenhorst@m2.uni-hannover.de> + Copyright (C) 2001 Adrian Schroeter <adrian@suse.de> + Copyright (C) 2003 Richard Lärkäng <richard@goteborg.utfors.se> + Copyright (C) 2003 Scott Wheeler <wheeler@kde.org> + Copyright (C) 2004, 2005 Benjamin Meyer <ben at meyerhome dot net> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef ENCODER_VORBIS_H +#define ENCODER_VORBIS_H + +#include <config.h> + +#ifdef HAVE_VORBIS + +#include <audiocdencoder.h> + +/** + * Ogg Vorbis encoder. + * This encoder is only enabled when HAVE_VORBIS is set. + * Check out http://www.vorbis.com/ for lots of information. + */ +class EncoderVorbis : public AudioCDEncoder { + +public: + EncoderVorbis(KIO::SlaveBase *slave); + ~EncoderVorbis(); + + virtual QString type() const { return "Ogg Vorbis"; }; + virtual bool init(); + virtual void loadSettings(); + virtual unsigned long size(long time_secs) const; + virtual const char * fileType() const { return "ogg"; }; + virtual const char * mimeType() const; + virtual void fillSongInfo( KCDDB::CDInfo info, int track, const QString &comment ); + virtual long readInit(long size); + virtual long read(int16_t * buf, int frames); + virtual long readCleanup(); + virtual QWidget* getConfigureWidget(KConfigSkeleton** manager) const; + +private: + long flush_vorbis(); + + class Private; + Private * d; + +}; + +#endif // HAVE_VORBIS + +#endif // ENCODER_VORBIS_H + diff --git a/kioslave/audiocd/plugins/vorbis/encodervorbisconfig.ui b/kioslave/audiocd/plugins/vorbis/encodervorbisconfig.ui new file mode 100644 index 00000000..17000745 --- /dev/null +++ b/kioslave/audiocd/plugins/vorbis/encodervorbisconfig.ui @@ -0,0 +1,425 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>EncoderVorbisConfig</class> +<widget class="QWidget"> + <property name="name"> + <cstring>VorbisConfig</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>375</width> + <height>408</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>kcfg_vorbis_enc_method</cstring> + </property> + <property name="title"> + <string>&Encoding Method</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>vorbis_enc_quality</cstring> + </property> + <property name="text"> + <string>Quality based</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>vorbis_enc_bitrate</cstring> + </property> + <property name="text"> + <string>Bitrate based</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>vorbis_bitrate_settings</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Vorbis Bitrate Settings</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QComboBox" row="0" column="1"> + <item> + <property name="text"> + <string>32 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>40 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>48 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>56 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>64 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>80 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>96 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>112 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>128 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>160 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>192 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>224 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>256 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>350 kbs</string> + </property> + </item> + <property name="name"> + <cstring>kcfg_vorbis_min_br</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="currentItem"> + <number>1</number> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>32 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>40 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>48 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>56 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>64 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>80 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>96 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>112 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>128 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>160 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>192 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>224 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>256 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>350 kbs</string> + </property> + </item> + <property name="name"> + <cstring>kcfg_vorbis_max_br</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="currentItem"> + <number>13</number> + </property> + </widget> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>kcfg_set_vorbis_min_br</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>M&inimal bitrate:</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>kcfg_set_vorbis_max_br</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Ma&ximal bitrate:</string> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <item> + <property name="text"> + <string>128 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>160 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>192 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>256 kbs</string> + </property> + </item> + <item> + <property name="text"> + <string>350 kbs</string> + </property> + </item> + <property name="name"> + <cstring>kcfg_vorbis_nominal_br</cstring> + </property> + <property name="currentItem"> + <number>1</number> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>kcfg_set_vorbis_nominal_br</cstring> + </property> + <property name="text"> + <string>A&verage bitrate:</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>vorbis_quality_settings</cstring> + </property> + <property name="title"> + <string>Vorbis &Quality Setting</string> + </property> + <property name="whatsThis" stdset="0"> + <string>You can set the quality of the encoded stream here. A higher value implies a higher quality but encodes slower.</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="KDoubleNumInput"> + <property name="name"> + <cstring>kcfg_vorbis_quality</cstring> + </property> + <property name="value"> + <number>0</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="maxValue"> + <number>10000</number> + </property> + <property name="precision"> + <number>1</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Higher is better but slower</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>GroupBox193</cstring> + </property> + <property name="title"> + <string>Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>kcfg_vorbis_comments</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Add &track information</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Add a description of the song to the file header. This makes it easy for the user to get advanced song information shown by his media player. You can get this information automatically via the Internet. Look at the <i>"CDDB Retrieval"</i> control module for details.</string> + </property> + </widget> + </vbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer9</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>51</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<connections> + <connection> + <sender>vorbis_enc_bitrate</sender> + <signal>toggled(bool)</signal> + <receiver>vorbis_bitrate_settings</receiver> + <slot>setShown(bool)</slot> + </connection> + <connection> + <sender>vorbis_enc_quality</sender> + <signal>toggled(bool)</signal> + <receiver>vorbis_quality_settings</receiver> + <slot>setShown(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>vorbis_enc_quality</tabstop> + <tabstop>kcfg_set_vorbis_min_br</tabstop> + <tabstop>kcfg_set_vorbis_max_br</tabstop> + <tabstop>kcfg_set_vorbis_nominal_br</tabstop> + <tabstop>kcfg_vorbis_min_br</tabstop> + <tabstop>kcfg_vorbis_max_br</tabstop> + <tabstop>kcfg_vorbis_nominal_br</tabstop> + <tabstop>kcfg_vorbis_quality</tabstop> + <tabstop>kcfg_vorbis_comments</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/kioslave/audiocd/plugins/wav/Makefile.am b/kioslave/audiocd/plugins/wav/Makefile.am new file mode 100644 index 00000000..82e6ab28 --- /dev/null +++ b/kioslave/audiocd/plugins/wav/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = -I$(srcdir)/.. $(all_includes) + +INCLUDES = -I$(top_srcdir)/libkcddb + +kde_module_LTLIBRARIES = libaudiocd_encoder_wav.la + +libaudiocd_encoder_wav_la_SOURCES = encoderwav.cpp encodercda.cpp + +libaudiocd_encoder_wav_la_LIBADD = $(LIB_KIO) ../libaudiocdplugins.la $(CDPARANOIA_LIBS) + +libaudiocd_encoder_wav_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries) + +pluginsdir = $(kde_datadir)/audiocd/plugins + +METASOURCES = AUTO diff --git a/kioslave/audiocd/plugins/wav/encodercda.cpp b/kioslave/audiocd/plugins/wav/encodercda.cpp new file mode 100644 index 00000000..fb8a794a --- /dev/null +++ b/kioslave/audiocd/plugins/wav/encodercda.cpp @@ -0,0 +1,67 @@ +/* + Copyright (C) 2000 Rik Hemsley (rikkus) <rik@kde.org> + Copyright (C) 2000, 2001, 2002 Michael Matz <matz@kde.org> + Copyright (C) 2001 Carsten Duvenhorst <duvenhorst@m2.uni-hannover.de> + Copyright (C) 2001 Adrian Schroeter <adrian@suse.de> + Copyright (C) 2003 Richard Lärkäng <richard@goteborg.utfors.se> + Copyright (C) 2003 Scott Wheeler <wheeler@kde.org> + Copyright (C) 2004, 2005 Benjamin Meyer <ben at meyerhome dot net> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "encodercda.h" + +class EncoderCda::Private +{ + public: + +}; + +unsigned long EncoderCda::size(long time_secs) const { + //return (time_secs * (44100 * 2 * 16))/8; + return (time_secs) * 176400; +} + +const char * EncoderCda::mimeType() const { + return "audio/x-cda"; +} + +// Remove this by calculating CD_FRAMESIZE_RAW from the frames +extern "C" +{ + #include <cdda_interface.h> +} + +inline int16_t swap16 (int16_t i) +{ + return (((i >> 8) & 0xFF) | ((i << 8) & 0xFF00)); +} + +long EncoderCda::read(int16_t * buf, int frames){ + QByteArray output; + int16_t i16 = 1; + /* WAV is defined to be little endian, so we need to swap it + on big endian platforms. */ + if (((char*)&i16)[0] == 0) + for (int i=0; i < 2 * frames; i++) + buf[i] = swap16 (buf[i]); + char * cbuf = reinterpret_cast<char *>(buf); + output.setRawData(cbuf, CD_FRAMESIZE_RAW); + ioslave->data(output); + output.resetRawData(cbuf, CD_FRAMESIZE_RAW); + return CD_FRAMESIZE_RAW; +} + diff --git a/kioslave/audiocd/plugins/wav/encodercda.h b/kioslave/audiocd/plugins/wav/encodercda.h new file mode 100644 index 00000000..0a95aa51 --- /dev/null +++ b/kioslave/audiocd/plugins/wav/encodercda.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2000 Rik Hemsley (rikkus) <rik@kde.org> + Copyright (C) 2000, 2001, 2002 Michael Matz <matz@kde.org> + Copyright (C) 2001 Carsten Duvenhorst <duvenhorst@m2.uni-hannover.de> + Copyright (C) 2001 Adrian Schroeter <adrian@suse.de> + Copyright (C) 2003 Richard Lärkäng <richard@goteborg.utfors.se> + Copyright (C) 2003 Scott Wheeler <wheeler@kde.org> + Copyright (C) 2004, 2005 Benjamin Meyer <ben at meyerhome dot net> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef ENCODER_CDA_H +#define ENCODER_CDA_H + +#include <audiocdencoder.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdlib.h> + +/** + * Raw cd "encoder" + * Does little more then copy the data and make sure it is in the right + * endian. + */ +class EncoderCda : public AudioCDEncoder { + +public: + EncoderCda(KIO::SlaveBase *slave) : AudioCDEncoder(slave) {}; + ~EncoderCda(){}; + virtual bool init(){ return true; }; + virtual void loadSettings(){}; + virtual unsigned long size(long time_secs) const; + virtual QString type() const { return "CDA"; }; + virtual const char * mimeType() const; + virtual const char * fileType() const { return "cda"; }; + virtual void fillSongInfo( KCDDB::CDInfo, int, const QString &){}; + virtual long readInit(long){ return 0; }; + virtual long read(int16_t * buf, int frames); + virtual long readCleanup(){ return 0; }; + +private: + class Private; + Private * d; + +}; + +#endif // ENCODER_CDA_H + diff --git a/kioslave/audiocd/plugins/wav/encoderwav.cpp b/kioslave/audiocd/plugins/wav/encoderwav.cpp new file mode 100644 index 00000000..ad658e2c --- /dev/null +++ b/kioslave/audiocd/plugins/wav/encoderwav.cpp @@ -0,0 +1,85 @@ +/* + Copyright (C) 2000 Rik Hemsley (rikkus) <rik@kde.org> + Copyright (C) 2000, 2001, 2002 Michael Matz <matz@kde.org> + Copyright (C) 2001 Carsten Duvenhorst <duvenhorst@m2.uni-hannover.de> + Copyright (C) 2001 Adrian Schroeter <adrian@suse.de> + Copyright (C) 2003 Richard Lärkäng <richard@goteborg.utfors.se> + Copyright (C) 2003 Scott Wheeler <wheeler@kde.org> + Copyright (C) 2004, 2005 Benjamin Meyer <ben at meyerhome dot net> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "encoderwav.h" + +extern "C" +{ + KDE_EXPORT void create_audiocd_encoders(KIO::SlaveBase *slave, QPtrList<AudioCDEncoder> &encoders) + { + encoders.append( new EncoderWav(slave)); + encoders.append( new EncoderCda(slave)); + } +} + +class EncoderWav::Private +{ + public: + +}; + +unsigned long EncoderWav::size(long time_secs) const { + return (EncoderCda::size(time_secs) + 44); +} + +const char * EncoderWav::mimeType() const { + return "audio/x-wav"; +} + +long EncoderWav::readInit(long byteCount){ + static char riffHeader[] = + { + 0x52, 0x49, 0x46, 0x46, // 0 "AIFF" + 0x00, 0x00, 0x00, 0x00, // 4 wavSize + 0x57, 0x41, 0x56, 0x45, // 8 "WAVE" + 0x66, 0x6d, 0x74, 0x20, // 12 "fmt " + 0x10, 0x00, 0x00, 0x00, // 16 + 0x01, 0x00, 0x02, 0x00, // 20 + 0x44, 0xac, 0x00, 0x00, // 24 + 0x10, 0xb1, 0x02, 0x00, // 28 + 0x04, 0x00, 0x10, 0x00, // 32 + 0x64, 0x61, 0x74, 0x61, // 36 "data" + 0x00, 0x00, 0x00, 0x00 // 40 byteCount + }; + + Q_INT32 wavSize(byteCount + 44 - 8); + + + riffHeader[4] = (wavSize >> 0 ) & 0xff; + riffHeader[5] = (wavSize >> 8 ) & 0xff; + riffHeader[6] = (wavSize >> 16) & 0xff; + riffHeader[7] = (wavSize >> 24) & 0xff; + + riffHeader[40] = (byteCount >> 0 ) & 0xff; + riffHeader[41] = (byteCount >> 8 ) & 0xff; + riffHeader[42] = (byteCount >> 16) & 0xff; + riffHeader[43] = (byteCount >> 24) & 0xff; + + QByteArray output; + output.setRawData(riffHeader, 44); + ioslave->data(output); + output.resetRawData(riffHeader, 44); + return 44; +} + diff --git a/kioslave/audiocd/plugins/wav/encoderwav.h b/kioslave/audiocd/plugins/wav/encoderwav.h new file mode 100644 index 00000000..09301ae5 --- /dev/null +++ b/kioslave/audiocd/plugins/wav/encoderwav.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2000 Rik Hemsley (rikkus) <rik@kde.org> + Copyright (C) 2000, 2001, 2002 Michael Matz <matz@kde.org> + Copyright (C) 2001 Carsten Duvenhorst <duvenhorst@m2.uni-hannover.de> + Copyright (C) 2001 Adrian Schroeter <adrian@suse.de> + Copyright (C) 2003 Richard Lärkäng <richard@goteborg.utfors.se> + Copyright (C) 2003 Scott Wheeler <wheeler@kde.org> + Copyright (C) 2004, 2005 Benjamin Meyer <ben at meyerhome dot net> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef ENCODER_WAV_H +#define ENCODER_WAV_H + +#include "encodercda.h" +#include <sys/stat.h> +#include <unistd.h> +#include <stdlib.h> + +/** + * Wav audio "encoder" + * Takes the CDA take and adds the standard wav header. + */ +class EncoderWav : public EncoderCda { + +public: + EncoderWav(KIO::SlaveBase *slave) : EncoderCda(slave) {}; + ~EncoderWav(){}; + virtual bool init(){ return true; }; + virtual unsigned long size(long time_secs) const; + virtual QString type() const { return "Wav"; }; + virtual const char * fileType() const { return "wav"; }; + virtual const char * mimeType() const; + virtual void fillSongInfo( KCDDB::CDInfo, int, const QString &){}; + virtual long readInit(long size); + +private: + class Private; + Private * d; + +}; + +#endif // ENCODER_WAV_H |