summaryrefslogtreecommitdiffstats
path: root/plugins/decoder/musepack/k3bmpcwrapper.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-03 02:15:56 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-03 02:15:56 +0000
commit50b48aec6ddd451a6d1709c0942477b503457663 (patch)
treea9ece53ec06fd0a2819de7a2a6de997193566626 /plugins/decoder/musepack/k3bmpcwrapper.cpp
downloadk3b-50b48aec6ddd451a6d1709c0942477b503457663.tar.gz
k3b-50b48aec6ddd451a6d1709c0942477b503457663.zip
Added abandoned KDE3 version of K3B
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k3b@1084400 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'plugins/decoder/musepack/k3bmpcwrapper.cpp')
-rw-r--r--plugins/decoder/musepack/k3bmpcwrapper.cpp193
1 files changed, 193 insertions, 0 deletions
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 <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * 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;
+}
+