You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
arts/flow/stereoeffectstack_impl.cc

180 lines
4.3 KiB

/*
Copyright (C) 2000 Stefan Westerfeld
stefan@space.twc.de
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., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "artsflow.h"
#include "flowsystem.h"
#include "stdsynthmodule.h"
#include "debug.h"
#include <iostream>
using namespace std;
using namespace Arts;
namespace Arts {
class StereoEffectStack_impl : public StereoEffectStack_skel,
public StdSynthModule
{
long nextID;
struct EffectEntry {
StereoEffect effect;
string name;
long id;
};
list<EffectEntry *> fx;
void xconnect(bool connect, Object from, string fromP, Object to, string toP)
{
if(connect)
from._node()->connect(fromP,to._node(),toP);
else
from._node()->disconnect(fromP,to._node(),toP);
}
void xvirtualize(bool connect, string myPort, Object impl, string implPort)
{
if(connect)
_node()->virtualize(myPort,impl._node(),implPort);
else
_node()->devirtualize(myPort,impl._node(),implPort);
}
void internalconnect(bool c)
{
if(fx.empty())
{
/* no effects - forward input through to output */
xvirtualize(c,"outleft",Object::_from_base(this->_copy()),"inleft");
xvirtualize(c,"outright",Object::_from_base(this->_copy()),"inright");
}
else
{
list<EffectEntry *>::iterator ei;
EffectEntry *laste = 0;
long count = 0;
for(ei = fx.begin(); ei != fx.end(); ei++, count++)
{
EffectEntry *e = *ei;
if(count == 0) /* top of chain? virtualize to effect */
{
xvirtualize(c,"inleft",e->effect,"inleft");
xvirtualize(c,"inright",e->effect,"inright");
}
else /* not top? connect last effect to current effect */
{
xconnect(c,laste->effect,"outleft",e->effect,"inleft");
xconnect(c,laste->effect,"outright",e->effect,"inright");
}
laste = e;
}
/* end: virtualize effect output to our output */
xvirtualize(c,"outleft",laste->effect,"outleft");
xvirtualize(c,"outright",laste->effect,"outright");
}
}
void disconnect() { internalconnect(false); }
void reconnect() { internalconnect(true); }
public:
StereoEffectStack_impl() : nextID(1)
{
reconnect();
}
~StereoEffectStack_impl()
{
// disconnect remaining effects
EffectEntry *laste = 0;
list<EffectEntry *>::iterator ei;
for(ei = fx.begin(); ei != fx.end(); ei++)
{
EffectEntry *e = *ei;
if(laste)
{
xconnect(false,laste->effect,"outleft",e->effect,"inleft");
xconnect(false,laste->effect,"outright",e->effect,"inright");
}
laste = e;
}
// delete remaining effect entries
for(ei = fx.begin(); ei != fx.end(); ei++)
delete *ei;
fx.clear();
}
long insertTop(StereoEffect effect, const string& name)
{
arts_return_val_if_fail(!effect.isNull(),0);
disconnect();
EffectEntry *e = new EffectEntry();
e->effect = effect;
e->name = name;
e->id = nextID++;
fx.push_front(e);
reconnect();
return e->id;
}
long insertBottom(StereoEffect effect, const string& name)
{
arts_return_val_if_fail(!effect.isNull(),0);
disconnect();
EffectEntry *e = new EffectEntry();
e->effect = effect;
e->name = name;
e->id = nextID++;
fx.push_back(e);
reconnect();
return e->id;
}
void remove(long ID)
{
arts_return_if_fail(ID != 0);
bool found = false;
disconnect();
list<EffectEntry *>::iterator ei = fx.begin();
while(ei != fx.end())
{
if((*ei)->id == ID) {
found = true;
delete (*ei);
fx.erase(ei);
ei = fx.begin();
}
else ei++;
}
if(!found) {
arts_warning("StereoEffectStack::remove failed. id %d not found?",
ID);
}
reconnect();
}
AutoSuspendState autoSuspend() { return asSuspend; }
};
REGISTER_IMPLEMENTATION(StereoEffectStack_impl);
}