diff --git a/CMakeLists.txt b/CMakeLists.txt index 513e4fa23..58811e025 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ INCLUDE(FindPkgConfig) SET(VERSION_MAJOR "0") SET(VERSION_MINOR "4") SET(VERSION_PATCH "0") -SET(VERSION_SUFFIX "beta") +SET(VERSION_SUFFIX "beta1") SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") IF(VERSION_SUFFIX) SET (VERSION "${VERSION}-${VERSION_SUFFIX}") diff --git a/ChangeLog b/ChangeLog index 532e8b00f..384b794e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2008-08-04 Tobias Doerffel + + * plugins/ladspa_effect/ladspa_effect.cpp: + * plugins/ladspa_effect/ladspa_subplugin_features.cpp: + * plugins/vst_effect/vst_subplugin_features.cpp: + * plugins/vst_effect/vst_effect.cpp: + * plugins/vst_effect/vst_effect_controls.cpp: + * include/plugin.h: + * include/base64.h: + * include/ladspa_base.h: + * src/core/plugin.cpp: + * src/core/effect_chain.cpp: + * src/core/mmp.cpp: + * src/core/ladspa_manager.cpp: + * CMakeLists.txt: + use XML rather than binary blobs for saving plugin-/effect-key + + * src/core/project_journal.cpp: + use random-number-generator correctly - fixes predictable random + numbers and avoids used Journalling-Object-IDs upon loading + project (closes #2036745) - anyways this still might happen under rare + circumstances and needs a further fix + 2008-08-03 Tobias Doerffel * include/lmms_math.h: diff --git a/include/base64.h b/include/base64.h index 4f54701c8..74578684f 100644 --- a/include/base64.h +++ b/include/base64.h @@ -2,7 +2,7 @@ * base64.h - namespace base64 with methods for encoding/decoding binary data * to/from base64 * - * Copyright (c) 2006 Tobias Doerffel + * Copyright (c) 2006-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -47,7 +47,9 @@ namespace base64 *_data = new char[*_size]; memcpy( *_data, data.constData(), *_size ); } + // deprecated!! QString encode( const QVariant & _data ); + // for compatibility-code only QVariant decode( const QString & _b64, QVariant::Type _force_type = QVariant::Invalid ); diff --git a/include/ladspa_base.h b/include/ladspa_base.h index ea6e427ec..d290f7baf 100644 --- a/include/ladspa_base.h +++ b/include/ladspa_base.h @@ -2,7 +2,7 @@ * ladspa_base.h - basic declarations concerning LADSPA * * Copyright (c) 2006-2007 Danny McRae - * Copyright (c) 2006-2007 Tobias Doerffel + * Copyright (c) 2006-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -74,8 +74,11 @@ inline plugin::descriptor::subPluginFeatures::key ladspaKeyToSubPluginKey( const QString & _name, const ladspa_key_t & _key ) { + plugin::descriptor::subPluginFeatures::key::attributeMap m; + m["file"] = _key.first; + m["plugin"] = _key.second; return( plugin::descriptor::subPluginFeatures::key( _desc, _name, - QVariant( QStringList() << _key.first << _key.second ) ) ); + m ) ); } diff --git a/include/plugin.h b/include/plugin.h index 0806260fd..c90b858c2 100644 --- a/include/plugin.h +++ b/include/plugin.h @@ -30,6 +30,7 @@ #include #include #include +#include #include "journalling_object.h" #include "mv_base.h" @@ -76,42 +77,23 @@ public: public: struct key { + typedef QMap attributeMap; + inline key( plugin::descriptor * _desc = NULL, const QString & _name = QString::null, - const QVariant & _user = QVariant() ) + const attributeMap & _am = + attributeMap() ) : desc( _desc ), name( _name ), - user( _user ) + attributes( _am ) { } - inline key( const QString & _dump_data ) - : - desc( NULL ) - { - const QList l = - base64::decode( _dump_data, - QVariant::List ). - toList(); - if( l.empty() ) - { - name = QString::null; - user = QVariant(); - } - else - { - name = l[0].toString(); - user = l[1]; - } - } + key( const QDomElement & _key ); - inline QString dumpBase64( void ) const - { - return( base64::encode( - QList() - << name << user ) ); - } + QDomElement saveXML( QDomDocument & + _doc ) const; inline bool isValid( void ) const { @@ -121,8 +103,8 @@ public: plugin::descriptor * desc; QString name; - QVariant user; - }; + attributeMap attributes; + } ; typedef QList keyList; @@ -140,8 +122,9 @@ public: const key * ) { } + virtual void listSubPluginKeys( plugin::descriptor *, - keyList & ) + keyList & ) { } @@ -154,8 +137,9 @@ public: protected: const plugin::PluginTypes m_type; - } - * sub_plugin_features; + } ; + + subPluginFeatures * sub_plugin_features; } ; diff --git a/plugins/ladspa_effect/ladspa_effect.cpp b/plugins/ladspa_effect/ladspa_effect.cpp index 4b3e04aa0..757769aa3 100644 --- a/plugins/ladspa_effect/ladspa_effect.cpp +++ b/plugins/ladspa_effect/ladspa_effect.cpp @@ -71,7 +71,7 @@ ladspaEffect::ladspaEffect( model * _parent, if( manager->getDescription( m_key ) == NULL ) { QMessageBox::warning( 0, "Effect", - "Unknown LADSPA plugin requested: " + m_key.first, + "Unknown LADSPA plugin requested: " + m_key.second, QMessageBox::Ok, QMessageBox::NoButton ); setOkay( FALSE ); return; @@ -437,7 +437,7 @@ void ladspaEffect::pluginInstantiation( void ) if( m_descriptor == NULL ) { QMessageBox::warning( 0, "Effect", - "Can't get LADSPA descriptor function: " + m_key.first, + "Can't get LADSPA descriptor function: " + m_key.second, QMessageBox::Ok, QMessageBox::NoButton ); setOkay( FALSE ); return; @@ -445,7 +445,7 @@ void ladspaEffect::pluginInstantiation( void ) if( m_descriptor->run == NULL ) { QMessageBox::warning( 0, "Effect", - "Plugin has no processor: " + m_key.first, + "Plugin has no processor: " + m_key.second, QMessageBox::Ok, QMessageBox::NoButton ); setDontRun( TRUE ); } @@ -456,7 +456,7 @@ void ladspaEffect::pluginInstantiation( void ) if( effect == NULL ) { QMessageBox::warning( 0, "Effect", - "Can't get LADSPA instance: " + m_key.first, + "Can't get LADSPA instance: " + m_key.second, QMessageBox::Ok, QMessageBox::NoButton ); setOkay( FALSE ); return; @@ -475,7 +475,7 @@ void ladspaEffect::pluginInstantiation( void ) m_ports[proc][port]->buffer ) ) { QMessageBox::warning( 0, "Effect", - "Failed to connect port: " + m_key.first, + "Failed to connect port: " + m_key.second, QMessageBox::Ok, QMessageBox::NoButton ); setDontRun( TRUE ); return; diff --git a/plugins/ladspa_effect/ladspa_subplugin_features.cpp b/plugins/ladspa_effect/ladspa_subplugin_features.cpp index 5ce78e6a8..873ef2da6 100644 --- a/plugins/ladspa_effect/ladspa_subplugin_features.cpp +++ b/plugins/ladspa_effect/ladspa_subplugin_features.cpp @@ -4,7 +4,7 @@ * hosting LADSPA-plugins * * Copyright (c) 2006-2007 Danny McRae - * Copyright (c) 2006-2007 Tobias Doerffel + * Copyright (c) 2006-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -162,10 +162,7 @@ void ladspaSubPluginFeatures::listSubPluginKeys( plugin::descriptor * _desc, ladspa_key_t ladspaSubPluginFeatures::subPluginKeyToLadspaKey( const key * _key ) { - QStringList list = _key->user.toStringList(); - if( list.empty() ) - { - return( ladspa_key_t() ); - } - return( ladspa_key_t( list.first(), list.last() ) ); + return( ladspa_key_t( _key->attributes["file"], + _key->attributes["plugin"] ) ); } + diff --git a/plugins/vst_effect/vst_effect.cpp b/plugins/vst_effect/vst_effect.cpp index 5b7344019..48f65f377 100644 --- a/plugins/vst_effect/vst_effect.cpp +++ b/plugins/vst_effect/vst_effect.cpp @@ -64,9 +64,9 @@ vstEffect::vstEffect( model * _parent, m_key( *_key ), m_vstControls( this ) { - if( !m_key.user.toString().isEmpty() ) + if( !m_key.attributes["file"].isEmpty() ) { - openPlugin( m_key.user.toString() ); + openPlugin( m_key.attributes["file"] ); } } @@ -152,6 +152,8 @@ void vstEffect::openPlugin( const QString & _plugin ) m_plugin->setTempo( engine::getSong()->getTempo() ); m_pluginMutex.unlock(); delete tf; + + m_key.attributes["file"] = _plugin; } diff --git a/plugins/vst_effect/vst_effect_controls.cpp b/plugins/vst_effect/vst_effect_controls.cpp index aac673d1b..f44b5deb3 100755 --- a/plugins/vst_effect/vst_effect_controls.cpp +++ b/plugins/vst_effect/vst_effect_controls.cpp @@ -56,7 +56,7 @@ void vstEffectControls::loadSettings( const QDomElement & _this ) void vstEffectControls::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - _this.setAttribute( "plugin", m_effect->m_key.user.toString() ); + _this.setAttribute( "plugin", m_effect->m_key.attributes["file"] ); m_effect->m_pluginMutex.lock(); if( m_effect->m_plugin != NULL ) { diff --git a/plugins/vst_effect/vst_subplugin_features.cpp b/plugins/vst_effect/vst_subplugin_features.cpp index 1f3dd05b9..7e6dc1b4c 100644 --- a/plugins/vst_effect/vst_subplugin_features.cpp +++ b/plugins/vst_effect/vst_subplugin_features.cpp @@ -45,7 +45,8 @@ void vstSubPluginFeatures::fillDescriptionWidget( QWidget * _parent, const key * _key ) { new QLabel( QWidget::tr( "Name: " ) + _key->name, _parent ); - new QLabel( QWidget::tr( "File: " ) + _key->user.toString(), _parent ); + new QLabel( QWidget::tr( "File: " ) + _key->attributes["file"], + _parent ); } @@ -61,8 +62,9 @@ void vstSubPluginFeatures::listSubPluginKeys( plugin::descriptor * _desc, for( QStringList::const_iterator it = dlls.begin(); it != dlls.end(); ++it ) { - _kl.push_back( key( _desc, QFileInfo( *it ).baseName(), - *it ) ); + effectKey::attributeMap am; + am["file"] = *it; + _kl.push_back( key( _desc, QFileInfo( *it ).baseName(), am ) ); } } diff --git a/src/core/effect_chain.cpp b/src/core/effect_chain.cpp index d51fe001e..877ab7970 100644 --- a/src/core/effect_chain.cpp +++ b/src/core/effect_chain.cpp @@ -62,7 +62,7 @@ void effectChain::saveSettings( QDomDocument & _doc, QDomElement & _this ) { QDomElement ef = ( *it )->saveState( _doc, _this ); ef.setAttribute( "name", ( *it )->getDescriptor()->name ); - ef.setAttribute( "key", ( *it )->getKey().dumpBase64() ); + ef.appendChild( ( *it )->getKey().saveXML( _doc ) ); } } @@ -85,10 +85,8 @@ void effectChain::loadSettings( const QDomElement & _this ) { QDomElement cn = node.toElement(); const QString name = cn.attribute( "name" ); - // we have this really convenient key-ctor - // which takes a QString and decodes the - // base64-data inside :-) - effectKey key( cn.attribute( "key" ) ); + effectKey key( cn.elementsByTagName( "key" ). + item( 0 ).toElement() ); effect * e = effect::instantiate( name, this, &key ); if( e->isOkay() ) { @@ -96,7 +94,7 @@ void effectChain::loadSettings( const QDomElement & _this ) { if( e->nodeName() == node.nodeName() ) { - e->restoreState( node.toElement() ); + e->restoreState( node.toElement() ); } } } diff --git a/src/core/ladspa_manager.cpp b/src/core/ladspa_manager.cpp index 136580e44..922a3e95d 100644 --- a/src/core/ladspa_manager.cpp +++ b/src/core/ladspa_manager.cpp @@ -136,7 +136,7 @@ void ladspaManager::addPlugins( ( descriptor = _descriptor_func( pluginIndex ) ) != NULL; ++pluginIndex ) { - ladspa_key_t key( QString( descriptor->Label ), _file ); + ladspa_key_t key( _file, QString( descriptor->Label ) ); if( m_ladspaManagerMap.contains( key ) ) { continue; @@ -167,7 +167,7 @@ void ladspaManager::addPlugins( { plugIn->type = OTHER; } - + m_ladspaManagerMap[key] = plugIn; } } diff --git a/src/core/mmp.cpp b/src/core/mmp.cpp index 09fae3bc6..194122d07 100644 --- a/src/core/mmp.cpp +++ b/src/core/mmp.cpp @@ -37,6 +37,8 @@ #include "config_mgr.h" #include "project_version.h" #include "song_editor.h" +#include "effect.h" + multimediaProject::typeDescStruct @@ -667,6 +669,46 @@ void multimediaProject::upgrade( void ) el.setAttribute( "src", s ); } } + + if( version < "0.4.0-beta1" ) + { + // convert binary effect-key-blobs to XML + QDomNodeList list; + list = elementsByTagName( "effect" ); + for( int i = 0; !list.item( i ).isNull(); ++i ) + { + QDomElement el = list.item( i ).toElement(); + QString k = el.attribute( "key" ); + if( !k.isEmpty() ) + { + const QList l = + base64::decode( k, QVariant::List ). + toList(); + if( !l.isEmpty() ) + { + QString name = l[0].toString(); + QVariant u = l[1]; + effectKey::attributeMap m; + // VST-effect? + if( u.type() == QVariant::String ) + { + m["file"] = u.toString(); + } + // LADSPA-effect? + else if( u.type() == + QVariant::StringList ) + { + const QStringList sl = + u.toStringList(); + m["plugin"] = sl.value( 0 ); + m["file"] = sl.value( 1 ); + } + effectKey key( NULL, name, m ); + el.appendChild( key.saveXML( *this ) ); + } + } + } + } /* if( version < "0.4.0-beta" ) { QDomNodeList list; diff --git a/src/core/plugin.cpp b/src/core/plugin.cpp index 01efd75b2..a6639c23e 100644 --- a/src/core/plugin.cpp +++ b/src/core/plugin.cpp @@ -205,5 +205,38 @@ pluginView * plugin::createView( QWidget * _parent ) +plugin::descriptor::subPluginFeatures::key::key( + const QDomElement & _key ) : + desc( NULL ), + name( _key.attribute( "key" ) ), + attributes() +{ + QDomNodeList l = _key.elementsByTagName( "attribute" ); + for( int i = 0; !l.item( i ).isNull(); ++i ) + { + QDomElement e = l.item( i ).toElement(); + attributes[e.attribute( "name" )] = e.attribute( "value" ); + } + +} + + + + +QDomElement plugin::descriptor::subPluginFeatures::key::saveXML( + QDomDocument & _doc ) const +{ + QDomElement e = _doc.createElement( "key" ); + for( attributeMap::const_iterator it = attributes.begin(); + it != attributes.end(); ++it ) + { + QDomElement a = _doc.createElement( "attribute" ); + a.setAttribute( "name", it.key() ); + a.setAttribute( "value", it.value() ); + e.appendChild( a ); + } + return( e ); +} + #endif