summaryrefslogtreecommitdiffstats
path: root/arts/modules/common/env_effectrackitem_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'arts/modules/common/env_effectrackitem_impl.cc')
-rw-r--r--arts/modules/common/env_effectrackitem_impl.cc400
1 files changed, 400 insertions, 0 deletions
diff --git a/arts/modules/common/env_effectrackitem_impl.cc b/arts/modules/common/env_effectrackitem_impl.cc
new file mode 100644
index 00000000..7872ce42
--- /dev/null
+++ b/arts/modules/common/env_effectrackitem_impl.cc
@@ -0,0 +1,400 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002-2003 Matthias Kretz <kretz@kde.org>
+ 2002 Arnold Krille <arnold@arnoldarts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ 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.
+
+*/
+// $Id$
+
+#include "artsmodulescommon.h"
+#include <debug.h>
+#include "env_item_impl.h"
+#include <connect.h>
+#include <stdio.h>
+#include <vector>
+#include <map>
+
+
+// Wether you are able to edit the name of the effectrack with an ugly LineInput or not.
+//#define EFFECTRACK_NAME
+// We should implement something like a ConfigWidget or at least a KLineInputBox or something...
+
+namespace Arts {
+namespace Environment {
+
+class EffectRackItem_impl : virtual public EffectRackItem_skel,
+ virtual public Item_impl
+{
+protected:
+ std::string _name;
+ AudioManagerClient _amClient;
+
+ struct RackWiring {
+ RackWiring( const std::string & type, AudioManagerClient _amClient )
+ : routedtomaster( false )
+ , amClient( _amClient )
+ {
+ effect = SubClass( type );
+
+ connect( input, effect );
+ connect( effect, output );
+ }
+
+ inline void setName( const std::string & efname )
+ {
+ name = efname;
+ input.busname( efname );
+ if( ! routedtomaster )
+ {
+ output.title( efname );
+ output.autoRestoreID( efname );
+ }
+ }
+
+ inline void start()
+ {
+ input.start();
+ effect.start();
+ output.start();
+ }
+
+ inline void stop()
+ {
+ input.stop();
+ effect.stop();
+ output.stop();
+ }
+
+ inline void master( bool tomaster )
+ {
+ routedtomaster = tomaster;
+
+ output.stop();
+ output = tomaster ? Synth_AMAN_PLAY( amClient ) : Synth_AMAN_PLAY();
+ connect( effect, output );
+ if( ! tomaster )
+ {
+ output.title( name );
+ output.autoRestoreID( name );
+ }
+ output.start();
+ }
+
+ bool routedtomaster;
+ std::string name;
+ std::string effectName;
+ Synth_BUS_DOWNLINK input;
+ Arts::StereoEffect effect;
+ Synth_AMAN_PLAY output;
+ AudioManagerClient amClient;
+ };
+ std::vector<RackWiring> _wirings;
+
+public:
+ EffectRackItem_impl()
+ : _name( "effect rack" )
+ , _amClient( amPlay, _name + " Master", "effectrack_" + _name )
+ {
+ // TODO: check if there's another effect rack with the same name already - if so prefix with 2./3./4.
+ }
+
+ // readonly attribute sequence<Arts::StereoEffect> effects;
+ std::vector<Arts::StereoEffect> *effects()
+ {
+ std::vector<Arts::StereoEffect> * effects = new std::vector<Arts::StereoEffect>;
+ for( std::vector<RackWiring>::iterator it = _wirings.begin(); it != _wirings.end(); ++it )
+ effects->push_back( it->effect );
+ return effects;
+ }
+
+ // attribute long effectCount;
+ long effectCount() { return _wirings.size(); }
+
+ // attribute string name;
+ void name(const std::string& newName) {
+ if(newName != _name)
+ {
+ _name = newName;
+ _amClient.title( _name + " Master" );
+ _amClient.autoRestoreID( "effectrack_" + _name );
+ for( unsigned int i = 0; i < _wirings.size(); i++ )
+ _wirings[i].setName( effectName( i, _wirings[ i ].effectName ) );
+ name_changed( newName );
+ }
+ }
+ std::string name() { return _name; }
+
+ void loadFromList(const std::vector<std::string>& /*list*/)
+ {
+ }
+
+ std::vector<std::string> *saveToList()
+ {
+ std::vector<std::string> *result = new std::vector<std::string>;
+ return result;
+ }
+
+ std::string effectName( int n, const std::string & en )
+ {
+ char * efname = new char[ _name.length() + en.length() + 128 ];
+ sprintf( efname, "%s%02d (%s)", _name.c_str(), n, en.c_str() );
+ return efname;
+ }
+
+ Arts::StereoEffect createEffect( const std::string & type, const std::string & name )
+ {
+ RackWiring wiring( type, _amClient );
+ wiring.setName( effectName( _wirings.size() + 1, name ) );
+ wiring.start();
+ _wirings.push_back( wiring );
+ return wiring.effect;
+ }
+
+ void delEffect( long pos )
+ {
+ _wirings[ pos ].stop();
+ _wirings.erase( _wirings.begin() + pos );
+ for( unsigned int i = pos; i < _wirings.size(); ++i )
+ _wirings[ i ].setName( effectName( i, _wirings[ i ].effectName ) );
+ }
+
+ void routeToMaster( long pos, bool tomaster )
+ {
+ _wirings[ pos ].master( tomaster );
+ }
+};
+REGISTER_IMPLEMENTATION(EffectRackItem_impl);
+}
+
+using namespace Environment;
+
+typedef WeakReference<VBox> VBox_wref;
+
+class EffectRackItemGui_impl : virtual public EffectRackItemGui_skel {
+private:
+ bool _active;
+ long _effectCount;
+ std::string _type;
+ EffectRackItem _effectRack;
+
+ /* widgets */
+ VBox_wref _widget;
+ HBox hbox;
+ VBox effect_vbox;
+#ifdef EFFECTRACK_NAME
+ LineEdit name;
+#endif
+ ComboBox typebox;
+ Button addbutton;
+ GenericGuiFactory guiFactory;
+ std::vector<EffectRackSlot> _slots;
+ std::map<std::string, std::string> typeforname;
+ std::map<std::string, std::string> namefortype;
+
+public:
+ EffectRackItemGui self() { return EffectRackItemGui::_from_base(_copy()); }
+
+ void redoGui()
+ {
+ VBox vbox = _widget;
+ if(vbox.isNull())
+ arts_warning("update with vbox null");
+ if(_effectRack.isNull())
+ arts_warning("update with _effectRack null");
+ if(!_effectRack.isNull() && !vbox.isNull())
+ {
+ vbox.spacing( 0 );
+ vbox.margin( 10 );
+ hbox = HBox( vbox );
+ hbox.spacing( 5 );
+ hbox.margin( 0 );
+
+#ifdef EFFECTRACK_NAME
+ name = LineEdit();
+ name.caption("name");
+ name.text(_effectRack.name());
+ name.parent(hbox);
+ connect(name,"text_changed", _effectRack, "name");
+#endif
+
+ std::vector<std::string> choices;
+ TraderQuery query;
+ query.supports( "Interface", "Arts::StereoEffect" );
+ query.supports( "Features", "RackGUI" );
+ std::vector<TraderOffer> *queryResults = query.query();
+ for(std::vector<TraderOffer>::iterator it = queryResults->begin(); it != queryResults->end(); ++it)
+ {
+ std::vector<std::string> * names = it->getProperty( "Name" );
+ std::string name = names->empty() ? it->interfaceName() : names->front();
+ delete names;
+ choices.push_back( name );
+ typeforname[ name ] = it->interfaceName();
+ namefortype[ it->interfaceName() ] = name;
+ }
+ delete queryResults;
+ typebox = ComboBox();
+ typebox.choices(choices);
+ typebox.value(_type);
+ typebox.parent(hbox);
+ connect(typebox,"value_changed", self(), "type");
+
+ addbutton = Button( "add", hbox );
+ connect( addbutton, "clicked_changed", self(), "addeffect" );
+
+ effect_vbox = VBox( vbox );
+ effect_vbox.margin( 0 );
+ effect_vbox.spacing( 5 );
+ effect_vbox.show();
+
+ Frame spacer;
+ spacer.parent( effect_vbox );
+ spacer.vSizePolicy( spExpanding );
+ spacer.show();
+ effect_vbox._addChild( spacer, "spacer" );
+
+ _slots.clear();
+
+ // add Arts::StereoEffect widgets
+ std::vector<Arts::StereoEffect> * effects = _effectRack.effects();
+ for( std::vector<Arts::StereoEffect>::iterator it = effects->begin(); it != effects->end(); ++it )
+ createEffectGui( *it );
+ delete effects;
+ }
+ else
+ {
+ /* FIXME: maybe insert a "dead" label here */
+ if(!vbox.isNull())
+ vbox.show();
+ effect_vbox = VBox::null();
+ hbox = HBox::null();
+ // name = LineEdit::null();
+ typebox = ComboBox::null();
+ _slots.clear();
+ }
+ }
+
+ void createEffectGui( Arts::StereoEffect effect )
+ {
+ Widget w = guiFactory.createGui( effect );
+ if( ! w.isNull() )
+ {
+ // insert effect GUI into the "Rack"
+ EffectRackSlot slot( effect_vbox, w, self() );
+ _slots.push_back( slot );
+ }
+ }
+
+ void removeSlot( EffectRackSlot slot )
+ {
+ unsigned int i;
+ for( i = 0; i < _slots.size() && ! _slots[ i ]._isEqual( slot ) ; ++i );
+ if( i < _slots.size() )
+ {
+ _slots.erase( _slots.begin() + i );
+ _effectRack.delEffect( i );
+ }
+ else
+ arts_warning( "WARNING: Trying to remove an unknown slot" );
+ }
+
+ void routeToMaster( EffectRackSlot slot, bool tomaster )
+ {
+ unsigned int i;
+ for( i = 0; i < _slots.size() && ! _slots[ i ]._isEqual( slot ) ; ++i );
+ if( i < _slots.size() )
+ _effectRack.routeToMaster( i, tomaster );
+ else
+ arts_warning( "WARNING: Trying to route an unknown slot" );
+ }
+
+ bool active() { return _active; }
+ void active(bool newActive)
+ {
+ if(newActive != _active)
+ {
+ _active = newActive;
+ if(!newActive)
+ _effectRack = EffectRackItem::null();
+ redoGui();
+ }
+ }
+
+ std::string type()
+ {
+ return _type;
+ }
+ void type(const std::string& t)
+ {
+ _type = typeforname[ t ];
+ }
+
+ bool addeffect() { return false; } //unused
+ void addeffect( bool clicked )
+ {
+ if( ! addbutton.clicked() || ! clicked )
+ return;
+
+ Arts::StereoEffect effect = _effectRack.createEffect( _type, namefortype[ _type ] );
+ createEffectGui( effect );
+ }
+
+ Widget initialize(EffectRackItem item)
+ {
+ VBox vbox;
+ vbox._addChild(self(),"the_gui_updating_widget");
+
+ _widget = vbox;
+ _effectRack = item;
+ _active = item.active();
+ _type = "Arts::Synth_VOICE_REMOVAL";
+ _effectCount = item.effectCount();
+
+ if(!_effectRack.isNull())
+ {
+ connect(_effectRack, "active_changed", self(), "active");
+ }
+ redoGui();
+
+ return vbox;
+ }
+};
+
+REGISTER_IMPLEMENTATION(EffectRackItemGui_impl);
+
+class EffectRackGuiFactory_impl : virtual public EffectRackGuiFactory_skel
+{
+public:
+ Widget createGui(Object object)
+ {
+ arts_return_val_if_fail(!object.isNull(), Arts::Widget::null());
+
+ std::string iface = object._interfaceName();
+ arts_return_val_if_fail(iface == "Arts::Environment::EffectRackItem",
+ Arts::Widget::null());
+ if(iface == "Arts::Environment::EffectRackItem")
+ {
+ EffectRackItem effectRack = DynamicCast(object);
+ arts_return_val_if_fail(!effectRack.isNull(), Arts::Widget::null());
+
+ EffectRackItemGui gui;
+ return gui.initialize(effectRack);
+ }
+ return Arts::Widget::null();
+ }
+};
+REGISTER_IMPLEMENTATION(EffectRackGuiFactory_impl);
+}
+// vim:ts=4:sw=4