diff options
Diffstat (limited to 'plugins/decoder/musepack')
-rw-r--r-- | plugins/decoder/musepack/Makefile.am | 16 | ||||
-rw-r--r-- | plugins/decoder/musepack/configure.in.bot | 12 | ||||
-rw-r--r-- | plugins/decoder/musepack/configure.in.in | 52 | ||||
-rw-r--r-- | plugins/decoder/musepack/k3bmpcdecoder.cpp | 111 | ||||
-rw-r--r-- | plugins/decoder/musepack/k3bmpcdecoder.h | 62 | ||||
-rw-r--r-- | plugins/decoder/musepack/k3bmpcdecoder.plugin | 9 | ||||
-rw-r--r-- | plugins/decoder/musepack/k3bmpcwrapper.cpp | 193 | ||||
-rw-r--r-- | plugins/decoder/musepack/k3bmpcwrapper.h | 58 |
8 files changed, 513 insertions, 0 deletions
diff --git a/plugins/decoder/musepack/Makefile.am b/plugins/decoder/musepack/Makefile.am new file mode 100644 index 0000000..beb7d63 --- /dev/null +++ b/plugins/decoder/musepack/Makefile.am @@ -0,0 +1,16 @@ +AM_CPPFLAGS = -I$(srcdir)/../../../libk3b/plugin \ + -I$(srcdir)/../../../libk3b/core \ + -I$(srcdir)/../../../libk3bdevice \ + $(all_includes) + +kde_module_LTLIBRARIES = libk3bmpcdecoder.la + +libk3bmpcdecoder_la_SOURCES = k3bmpcdecoder.cpp k3bmpcwrapper.cpp + +libk3bmpcdecoder_la_LIBADD = ../../../libk3b/libk3b.la $(MPC_LIBS) +libk3bmpcdecoder_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries) + +pluginsdir = $(kde_datadir)/k3b/plugins +plugins_DATA = k3bmpcdecoder.plugin + +METASOURCES = AUTO diff --git a/plugins/decoder/musepack/configure.in.bot b/plugins/decoder/musepack/configure.in.bot new file mode 100644 index 0000000..8fb871b --- /dev/null +++ b/plugins/decoder/musepack/configure.in.bot @@ -0,0 +1,12 @@ +echo "" + +if test x$have_mpc = xyes; then + echo "K3b - Musepack support: yes" +else + echo "K3b - Musepack support: no" +if test "$ac_cv_use_mpc" = "yes"; then + echo "K3b - You are missing the Musepack headers and libraries >= 1.1." + echo "K3b - The Musepack audio decoding plugin won't be compiled." +fi +fi + diff --git a/plugins/decoder/musepack/configure.in.in b/plugins/decoder/musepack/configure.in.in new file mode 100644 index 0000000..42d24c0 --- /dev/null +++ b/plugins/decoder/musepack/configure.in.in @@ -0,0 +1,52 @@ +dnl --------- MUSEPACK CHECK --------------- + +AC_ARG_WITH( + musepack, + AS_HELP_STRING( + [--without-musepack], + [build K3b without Musepack audio support (default=no)]), + [ac_cv_use_mpc=$withval], + [ac_cv_use_mpc=yes] +) + +have_mpc=no +if test "$ac_cv_use_mpc" = "yes"; then + + dnl - search for both the new and the old naming - + + KDE_CHECK_HEADERS(mpcdec/mpcdec.h, [ + AC_CHECK_LIB(mpcdec, mpc_decoder_setup, [ + have_mpc=yes + MPC_LIBS="-lmpcdec" + AC_DEFINE( + MPC_HEADER_FILE, + <mpcdec/mpcdec.h>, + [The header to include for MPC decoding.]) + ], + [], [], []) + ]) + + if test "$have_mpc" = "no"; then + KDE_CHECK_HEADERS(musepack/musepack.h, [ + AC_CHECK_LIB(musepack, mpc_decoder_setup, [ + have_mpc=yes + MPC_LIBS="-lmusepack" + AC_DEFINE( + MPC_HEADER_FILE, + <musepack/musepack.h>, + [The header to include for MPC decoding.] + ) + AC_DEFINE( + mpc_bool_t, + BOOL, + [backwards compatibility stuff] + ) + ], [], []) + ]) + fi +fi +AC_SUBST(MPC_LIBS) + +AM_CONDITIONAL(include_MPC, [test x$have_mpc = xyes]) + +dnl --------- MUSEPACK CHECK END ----------- diff --git a/plugins/decoder/musepack/k3bmpcdecoder.cpp b/plugins/decoder/musepack/k3bmpcdecoder.cpp new file mode 100644 index 0000000..0cdf644 --- /dev/null +++ b/plugins/decoder/musepack/k3bmpcdecoder.cpp @@ -0,0 +1,111 @@ +/* + * + * $Id: k3bmpcdecoder.cpp 619556 2007-01-03 17:38:12Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include <config.h> + +#include "k3bmpcdecoder.h" +#include "k3bmpcwrapper.h" + +#include <k3bpluginfactory.h> + +#include <klocale.h> + + +K_EXPORT_COMPONENT_FACTORY( libk3bmpcdecoder, K3bPluginFactory<K3bMpcDecoderFactory>( "libk3bmpcdecoder" ) ) + + +K3bMpcDecoderFactory::K3bMpcDecoderFactory( QObject* parent, const char* name ) + : K3bAudioDecoderFactory( parent, name ) +{ +} + + +K3bMpcDecoderFactory::~K3bMpcDecoderFactory() +{ +} + + +K3bAudioDecoder* K3bMpcDecoderFactory::createDecoder( QObject* parent, + const char* name ) const +{ + return new K3bMpcDecoder( parent, name ); +} + + +bool K3bMpcDecoderFactory::canDecode( const KURL& url ) +{ + K3bMpcWrapper w; + return w.open( url.path() ); +} + + + + + + +K3bMpcDecoder::K3bMpcDecoder( QObject* parent, const char* name ) + : K3bAudioDecoder( parent, name ) +{ + m_mpc = new K3bMpcWrapper(); +} + + +K3bMpcDecoder::~K3bMpcDecoder() +{ + delete m_mpc; +} + + +QString K3bMpcDecoder::fileType() const +{ + return i18n("Musepack"); +} + + +bool K3bMpcDecoder::analyseFileInternal( K3b::Msf& frames, int& samplerate, int& ch ) +{ + if( m_mpc->open( filename() ) ) { + frames = m_mpc->length(); + samplerate = m_mpc->samplerate(); + ch = m_mpc->channels(); + + // call addTechnicalInfo and addMetaInfo here + + return true; + } + else + return false; +} + + +bool K3bMpcDecoder::initDecoderInternal() +{ + return m_mpc->open( filename() ); +} + + +bool K3bMpcDecoder::seekInternal( const K3b::Msf& msf ) +{ + return m_mpc->seek( msf ); +} + + +int K3bMpcDecoder::decodeInternal( char* _data, int maxLen ) +{ + return m_mpc->decode( _data, maxLen ); +} + + +#include "k3bmpcdecoder.moc" diff --git a/plugins/decoder/musepack/k3bmpcdecoder.h b/plugins/decoder/musepack/k3bmpcdecoder.h new file mode 100644 index 0000000..74dc509 --- /dev/null +++ b/plugins/decoder/musepack/k3bmpcdecoder.h @@ -0,0 +1,62 @@ +/* + * + * $Id: k3bmpcdecoder.h 619556 2007-01-03 17:38:12Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#ifndef _K3B_MPC_DECODER_H_ +#define _K3B_MPC_DECODER_H_ + +#include <k3baudiodecoder.h> + +class K3bMpcWrapper; + + +class K3bMpcDecoderFactory : public K3bAudioDecoderFactory +{ + Q_OBJECT + + public: + K3bMpcDecoderFactory( QObject* parent = 0, const char* name = 0 ); + ~K3bMpcDecoderFactory(); + + bool canDecode( const KURL& filename ); + + int pluginSystemVersion() const { return 3; } + + K3bAudioDecoder* createDecoder( QObject* parent = 0, + const char* name = 0 ) const; +}; + + +class K3bMpcDecoder : public K3bAudioDecoder +{ + Q_OBJECT + + public: + K3bMpcDecoder( QObject* parent = 0, const char* name = 0 ); + ~K3bMpcDecoder(); + + QString fileType() const; + + protected: + bool analyseFileInternal( K3b::Msf& frames, int& samplerate, int& ch ); + bool initDecoderInternal(); + bool seekInternal( const K3b::Msf& ); + + int decodeInternal( char* _data, int maxLen ); + + private: + K3bMpcWrapper* m_mpc; +}; + +#endif diff --git a/plugins/decoder/musepack/k3bmpcdecoder.plugin b/plugins/decoder/musepack/k3bmpcdecoder.plugin new file mode 100644 index 0000000..6e350dc --- /dev/null +++ b/plugins/decoder/musepack/k3bmpcdecoder.plugin @@ -0,0 +1,9 @@ +[K3b Plugin] +Lib=libk3bmpcdecoder +Group=AudioDecoder +Name=K3b Musepack Decoder +Author=Sebastian Trueg +Version=1.0 +Comment=Decoding module to decode Musepack audio files +License=GPL diff --git a/plugins/decoder/musepack/k3bmpcwrapper.cpp b/plugins/decoder/musepack/k3bmpcwrapper.cpp new file mode 100644 index 0000000..9f54b28 --- /dev/null +++ b/plugins/decoder/musepack/k3bmpcwrapper.cpp @@ -0,0 +1,193 @@ +/* + * + * $Id: k3bmpcwrapper.cpp 619556 2007-01-03 17:38:12Z trueg $ + * Copyright (C) 2005 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include "k3bmpcwrapper.h" + +#include <kdebug.h> +#include <qfile.h> + + +mpc_int32_t read_impl( void* data, void* ptr, mpc_int32_t size ) +{ + QFile* input = static_cast<QFile*>( data ); + return input->readBlock( (char*)ptr, size ); +} + + +mpc_bool_t seek_impl( void* data, mpc_int32_t offset ) +{ + QFile* input = static_cast<QFile*>( data ); + return input->at( offset ); +} + +mpc_int32_t tell_impl( void* data ) +{ + QFile* input = static_cast<QFile*>( data ); + return input->at(); +} + +mpc_int32_t get_size_impl( void* data ) +{ + QFile* input = static_cast<QFile*>( data ); + return input->size(); +} + +mpc_bool_t canseek_impl( void* ) +{ + return true; +} + + +#ifdef MPC_FIXED_POINT +static int shift_signed( MPC_SAMPLE_FORMAT val, int shift ) +{ + if(shift > 0) + val <<= shift; + else if(shift < 0) + val >>= -shift; + return (int) val; +} +#endif + + +K3bMpcWrapper::K3bMpcWrapper() +{ + m_input = new QFile(); + + m_reader = new mpc_reader; + m_reader->read = read_impl; + m_reader->seek = seek_impl; + m_reader->tell = tell_impl; + m_reader->get_size = get_size_impl; + m_reader->canseek = canseek_impl; + m_reader->data = m_input; + + m_decoder = new mpc_decoder; + + m_info = new mpc_streaminfo; +} + + +K3bMpcWrapper::~K3bMpcWrapper() +{ + close(); + + delete m_reader; + delete m_decoder; + delete m_info; + delete m_input; +} + + +bool K3bMpcWrapper::open( const QString& filename ) +{ + close(); + + m_input->setName( filename ); + + if( m_input->open( IO_ReadOnly ) ) { + mpc_streaminfo_init( m_info ); + if( mpc_streaminfo_read( m_info, m_reader ) != ERROR_CODE_OK ) { + kdDebug() << "(K3bMpcWrapper) Not a valid musepack file: \"" << filename << "\"" << endl; + return false; + } + else { + mpc_decoder_setup( m_decoder, m_reader ); + if( !mpc_decoder_initialize( m_decoder, m_info ) ) { + kdDebug() << "(K3bMpcWrapper) failed to initialize the Musepack decoder." << endl; + close(); + return false; + } + else { + kdDebug() << "(K3bMpcWrapper) valid musepack file. " + << channels() << " Channels and Samplerate: " << samplerate() << endl; + return true; + } + } + } + else + return false; +} + + +void K3bMpcWrapper::close() +{ + m_input->close(); +} + + +int K3bMpcWrapper::decode( char* data, int max ) +{ + // FIXME: make this a member variable + MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH]; + + unsigned int samples = mpc_decoder_decode( m_decoder, sample_buffer, 0, 0 ); + + if( samples*channels()*2 > (unsigned int)max ) { + kdDebug() << "(K3bMpcWrapper) buffer not big enough." << endl; + return -1; + } + + static const unsigned int bps = 16; + static const int clip_min = -1 << (bps - 1); + static const int clip_max = (1 << (bps - 1)) - 1; + static const int float_scale = 1 << (bps - 1); + + for( unsigned int n = 0; n < samples*channels(); ++n ) { + int val = 0; + +#ifdef MPC_FIXED_POINT + val = shift_signed( sample_buffer[n], + bps - MPC_FIXED_POINT_SCALE_SHIFT); +#else + val = (int)(sample_buffer[n] * float_scale); +#endif + + if( val < clip_min ) + val = clip_min; + else if( val > clip_max ) + val = clip_max; + + data[2*n] = (val>>8) & 0xff; + data[2*n+1] = val & 0xff; + } + + return samples*channels()*2; +} + + +bool K3bMpcWrapper::seek( const K3b::Msf& msf ) +{ + return mpc_decoder_seek_seconds( m_decoder, (double)msf.totalFrames()/75.0 ); +} + + +K3b::Msf K3bMpcWrapper::length() const +{ + return K3b::Msf::fromSeconds( mpc_streaminfo_get_length( m_info ) ); +} + + +int K3bMpcWrapper::samplerate() const +{ + return m_info->sample_freq; +} + + +unsigned int K3bMpcWrapper::channels() const +{ + return m_info->channels; +} + diff --git a/plugins/decoder/musepack/k3bmpcwrapper.h b/plugins/decoder/musepack/k3bmpcwrapper.h new file mode 100644 index 0000000..743e25f --- /dev/null +++ b/plugins/decoder/musepack/k3bmpcwrapper.h @@ -0,0 +1,58 @@ +/* + * + * $Id: k3bmpcwrapper.h 630384 2007-02-05 09:33:17Z mlaurent $ + * Copyright (C) 2005 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#ifndef _K3B_MPC_WRAPPER_H_ +#define _K3B_MPC_WRAPPER_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qstring.h> + +#include <k3bmsf.h> + +#include MPC_HEADER_FILE + +class QFile; + + +class K3bMpcWrapper +{ + public: + K3bMpcWrapper(); + ~K3bMpcWrapper(); + + bool open( const QString& filename ); + void close(); + + int decode( char*, int max ); + + bool seek( const K3b::Msf& ); + + K3b::Msf length() const; + int samplerate() const; + unsigned int channels() const; + + QFile* input() const { return m_input; } + + private: + QFile* m_input; + mpc_reader* m_reader; + mpc_decoder* m_decoder; + mpc_streaminfo* m_info; +}; + +#endif |