Hi All,
Attached you will find a patch for giving AudioSource and AudioSink
multiple ports.
I tested it manually and ran the testsuite (there is a second patch for
the testsuite).
There is one caveat: it does not seem possible to retain the old naming
scheme when loading from a .clamnetwork file where a port has the name
AudioIn or AudioOut; instead, they're now numbered (source/sinkname.number):
AudioSource.0
AudioSource.1
... etc
In the jack connections the dot becomes an underscore (AudioSource_1 ...
etc).
So the clamnetworks need to be updated - attached you will find an
commandfile for the clamrefactor.py script.
The reason for the namechange is that ports are constructed with a name
which should match with the name in the xml file, but at construcion
time this name from the xml file is not known. This went ok because the
code always had 'AudioIn/Out' and this always matched with the xml file,
as there was but one port and one portname for a source or sink.
An alternative might be to create 'unnamed' ports (add a constructor,
the default arguments are in the way), add a 'setname' function to the
port and then call this when the xml is loaded. But it seems to me this
would add a lot of complexity.
When there is only 1 port in the source/sink, the jackport is named
after the source/sink so when you have meaningfull names in your
clamnetworks, these show in the jack connection viewer.
I tested it and it looks good, but as I am new to CLAM I might missed
(obvious) things; so please review.
Best, Dirk
Index: Flow/Networks/BackEnds/JACKNetworkPlayer.cxx
===================================================================
--- Flow/Networks/BackEnds/JACKNetworkPlayer.cxx (revision 13145)
+++ Flow/Networks/BackEnds/JACKNetworkPlayer.cxx (working copy)
@@ -1,8 +1,11 @@
#include "JACKNetworkPlayer.hxx"
#include "PushFlowControl.hxx"
+#include "AudioSource.hxx"
+#include "AudioSink.hxx"
#include <iostream>
+
namespace CLAM
{
@@ -86,55 +89,79 @@
void JACKNetworkPlayer::RegisterInputPorts(const Network& net)
{
-
Network::AudioSources sources=net.getOrderedSources();
CLAM_ASSERT( _sourceJackBindings.empty(),
"JACKNetworkPlayer::RegisterInputPorts() : there are already registered input ports");
- SourceJackBinding pair;
//Get them from the Network and add it to local list
for (Network::AudioSources::const_iterator it=sources.begin(); it!=sources.end(); it++)
{
- //Get Processing address
- pair.source=*it;
- pair.source->SetFrameAndHopSize(_jackBufferSize);
+ std::string processingName = net.GetNetworkId(*it);
- //Register port on the JACK server
- const std::string & processingName = net.GetNetworkId(*it);
- pair.jackPort=jack_port_register (_jackClient,
- processingName.c_str(),
- JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
+ AudioSource::Ports ports = (*it)->GetPorts();
+ for(unsigned port = 0; port < ports.size(); ++port)
+ {
+ //Get Processing address
+ SourceJackBinding pair;
+ pair.source=*it;
+ pair.source->SetFrameAndHopSize(_jackBufferSize, port);
- //Add the pair (jack port, clam jack receiver) to the list
- _sourceJackBindings.push_back(pair);
+ //Register port on the JACK server
+ std::stringstream portName;
+ if (ports.size() == 1)
+ portName << processingName << "." << ports[port].mAudioOut->GetName();
+ else
+ portName << processingName << "_" << port;
+
+ pair.jackPort = jack_port_register(_jackClient, portName.str().c_str(),
+ JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
+
+ // the index is used when there are more ports in an audiosource
+ // to decide which port should receive the data
+ pair.port = port;
+
+ //Add the pair (jack port, clam jack receiver) to the list
+ _sourceJackBindings.push_back(pair);
+ }
}
}
void JACKNetworkPlayer::RegisterOutputPorts(const Network& net)
{
-
Network::AudioSinks sinks=net.getOrderedSinks();
CLAM_ASSERT( _sinkJackBindings.empty(),
"JACKNetworkPlayer::RegisterOutputPorts() : there are already registered output ports");
- SinkJackBinding pair;
-
for (Network::AudioSinks::const_iterator it=sinks.begin(); it!=sinks.end(); it++)
{
- //Get Processing address
- pair.sink=*it;
- pair.sink->SetFrameAndHopSize(_jackBufferSize);
+ std::string processingName = net.GetNetworkId( *it );
- //Register port on the JACK server
- const std::string & processingName = net.GetNetworkId( *it );
- pair.jackPort=jack_port_register (_jackClient,
- processingName.c_str(),
- JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+ CLAM::AudioSink::Ports ports = (*it)->GetPorts();
+ for(unsigned port = 0; port < ports.size(); ++port)
+ {
+ //Get Processing address
+ SinkJackBinding pair;
+ pair.sink=*it;
+ pair.sink->SetFrameAndHopSize(_jackBufferSize, port);
- //Add the pair (jack port, clam jack receiver) to the list
- _sinkJackBindings.push_back(pair);
+ //Register port on the JACK server
+ std::stringstream portName;
+ if (ports.size() == 1)
+ portName << processingName;
+ else
+ portName << processingName << "_" << port;
+
+ pair.jackPort=jack_port_register (_jackClient, portName.str().c_str(),
+ JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+
+ pair.port = port;
+
+ //Add the pair (jack port, clam jack receiver) to the list
+ _sinkJackBindings.push_back(pair);
+ }
+
}
}
@@ -161,7 +188,7 @@
}
_sourceJackBindings.clear();
}
-
+
void JACKNetworkPlayer::CopyJackBuffersToGenerators(const jack_nframes_t nframes)
{
for (SourceJackBindings::iterator it=_sourceJackBindings.begin(); it!=_sourceJackBindings.end(); it++)
@@ -170,7 +197,7 @@
jack_default_audio_sample_t *jackInBuffer =
(jack_default_audio_sample_t*) jack_port_get_buffer ( it->jackPort, nframes);
//Tell the AudioSource where to look for data in its Do()
- it->source->SetExternalBuffer( jackInBuffer, nframes );
+ it->source->SetExternalBuffer( jackInBuffer, nframes, it->port);
}
}
@@ -182,7 +209,7 @@
jack_default_audio_sample_t *jackOutBuffer =
(jack_default_audio_sample_t*) jack_port_get_buffer ( it->jackPort, nframes);
//Tell the AudioSource where to copy data consumed in its Do()
- it->sink->SetExternalBuffer( jackOutBuffer, nframes);
+ it->sink->SetExternalBuffer( jackOutBuffer, nframes, it->port);
}
}
Index: Flow/Networks/BackEnds/JACKNetworkPlayer.hxx
===================================================================
--- Flow/Networks/BackEnds/JACKNetworkPlayer.hxx (revision 13145)
+++ Flow/Networks/BackEnds/JACKNetworkPlayer.hxx (working copy)
@@ -3,6 +3,7 @@
#include <iostream>
#include <string>
+#include <vector>
#include "NetworkPlayer.hxx"
#include "Network.hxx"
#include <jack/jack.h>
@@ -21,7 +22,9 @@
}
jack_port_t* jackPort;
AudioSource* source;
+ unsigned port;
};
+ typedef std::vector<SourceJackBinding> SourceJackBindings;
struct SinkJackBinding
{
@@ -31,15 +34,17 @@
}
jack_port_t* jackPort;
AudioSink* sink;
+ unsigned port;
};
- typedef std::vector<SourceJackBinding> SourceJackBindings;
typedef std::vector<SinkJackBinding> SinkJackBindings;
+
struct JackConnection
{
std::string processingName;
const char ** outsideConnections;
};
typedef std::list<JackConnection> JackConnections;
+
private:
int _jackSampleRate;
int _jackBufferSize;
@@ -58,6 +63,9 @@
jack_client_t * _jackClient;
std::string _jackClientName;
+private:
+ void AddSourceJackBinding(Network::AudioSources::const_iterator& it, std::string const& name, unsigned index);
+
public:
JACKNetworkPlayer(const std::string & name="CLAM network player");
virtual ~JACKNetworkPlayer();
Index: Processing/AudioSource.cxx
===================================================================
--- Processing/AudioSource.cxx (revision 13150)
+++ Processing/AudioSource.cxx (working copy)
@@ -4,7 +4,8 @@
namespace CLAM
{
-namespace Hidden
+
+namespace
{
static const char* metadata[] = {
"key", "AudioSource",
@@ -19,39 +20,72 @@
bool AudioSource::Do()
{
- CLAM::Audio& so=mOut.GetAudio();
- CLAM_DEBUG_ASSERT(!mFloatBuffer || !mDoubleBuffer, "AudioSource: Just one buffer should be set");
- CLAM_DEBUG_ASSERT(mFloatBuffer || mDoubleBuffer, "AudioSource: No external buffer set");
- CLAM_DEBUG_ASSERT(mBufferSize>0, "AudioSource: internal buffer size must be greater than 0");
- CLAM::TData * audioBuffer = so.GetBuffer().GetPtr();
- if (mFloatBuffer)
- for (unsigned i=0; i<mBufferSize; i++)
- audioBuffer[i] = mFloatBuffer[i];
- else
- for (unsigned i=0; i<mBufferSize; i++)
- audioBuffer[i] = mDoubleBuffer[i];
+ for (Ports::iterator it = _ports.begin(); it != _ports.end(); ++it)
+ {
+ Port& port = (*it);
+ AudioOutPort* out = port.mAudioOut;
- for (unsigned i=mBufferSize; i<mOut.GetSize(); i++)
- audioBuffer[i] = 0.;
- mOut.Produce();
+ CLAM::Audio& so=out->GetAudio();
+ CLAM_DEBUG_ASSERT(!port.mFloatBuffer || !port.mDoubleBuffer, "AudioSource: Just one buffer should be set");
+ CLAM_DEBUG_ASSERT(port.mFloatBuffer || port.mDoubleBuffer, "AudioSource: No external buffer set");
+ CLAM_DEBUG_ASSERT(port.mBufferSize>0, "AudioSource: internal buffer size must be greater than 0");
+ CLAM::TData * audioBuffer = so.GetBuffer().GetPtr();
+ if (port.mFloatBuffer)
+ for (unsigned i=0; i<port.mBufferSize; i++)
+ audioBuffer[i] = port.mFloatBuffer[i];
+ else
+ for (unsigned i=0; i<port.mBufferSize; i++)
+ audioBuffer[i] = port.mDoubleBuffer[i];
+
+ for (unsigned i=port.mBufferSize; i<out->GetSize(); i++)
+ audioBuffer[i] = 0.;
+ out->Produce();
+ }
return true;
}
+void AudioSource::SetExternalBuffer(const float* buf, unsigned nframes, unsigned index)
+{
+ CLAM_ASSERT(index < _ports.size(), "AudioOutPort index out of range");
+ Port& port = _ports[index];
+ port.mAudioOut->SetSize(nframes);
+ port.mAudioOut->SetHop(nframes);
+ port.mFloatBuffer = buf;
+ port.mBufferSize = nframes;
+ port.mDoubleBuffer = 0;
+}
+
+void AudioSource::SetExternalBuffer(const double* buf, unsigned nframes, unsigned index)
+{
+ CLAM_ASSERT(index < _ports.size(), "AudioOutPort index out of range");
+ Port& port = _ports[index];
+ port.mAudioOut->SetSize(nframes);
+ port.mAudioOut->SetHop(nframes);
+ port.mDoubleBuffer = buf;
+ port.mBufferSize = nframes;
+ port.mFloatBuffer = 0;
+}
+
void AudioSource::SetExternalBuffer(const float* buf, unsigned nframes)
{
- mFloatBuffer = buf;
- mBufferSize = nframes;
- mDoubleBuffer = 0;
- mOut.SetSize(nframes);
- mOut.SetHop(nframes);
+ CLAM_ASSERT(1 == _ports.size(), "AudioOutPort index out of range");
+ Port& port = _ports[0];
+ port.mAudioOut->SetSize(nframes);
+ port.mAudioOut->SetHop(nframes);
+ port.mFloatBuffer = buf;
+ port.mBufferSize = nframes;
+ port.mDoubleBuffer = 0;
}
+
void AudioSource::SetExternalBuffer(const double* buf, unsigned nframes)
{
- mDoubleBuffer = buf;
- mBufferSize = nframes;
- mFloatBuffer = 0;
- mOut.SetSize(nframes);
- mOut.SetHop(nframes);
+ CLAM_ASSERT(1 == _ports.size(), "AudioOutPort index out of range");
+ Port& port = _ports[0];
+ port.mAudioOut->SetSize(nframes);
+ port.mAudioOut->SetHop(nframes);
+ port.mDoubleBuffer = buf;
+ port.mBufferSize = nframes;
+ port.mFloatBuffer = 0;
}
} //namespace CLAM
Index: Processing/AudioSink.cxx
===================================================================
--- Processing/AudioSink.cxx (revision 13150)
+++ Processing/AudioSink.cxx (working copy)
@@ -7,7 +7,7 @@
namespace CLAM
{
-namespace Hidden
+namespace
{
static const char* metadata[] = {
"key", "AudioSink",
@@ -19,37 +19,72 @@
};
static FactoryRegistrator<ProcessingFactory, AudioSink> reg = metadata;
}
-
bool AudioSink::Do()
{
- const CLAM::Audio& so=mIn.GetAudio();
- CLAM_DEBUG_ASSERT(mFloatBuffer, "No float buffer");
- CLAM_DEBUG_ASSERT(!mDoubleBuffer, "There should not be double buffer");
- CLAM_DEBUG_ASSERT(mBufferSize>0, "internal buffer size must be greater than 0");
- const CLAM::TData * audioBuffer = so.GetBuffer().GetPtr();
- for (unsigned i=0; i<mBufferSize; i++)
- mFloatBuffer[i] = audioBuffer[i];
- mIn.Consume();
+ for (Ports::iterator it = _ports.begin(); it != _ports.end(); ++it)
+ {
+ Port& port = (*it);
+ AudioInPort* in = port.mAudioIn;
+
+ const CLAM::Audio& so=in->GetAudio();
+ CLAM_DEBUG_ASSERT(port.mFloatBuffer, "No float buffer");
+ CLAM_DEBUG_ASSERT(!port.mDoubleBuffer, "There should not be double buffer");
+ CLAM_DEBUG_ASSERT(port.mBufferSize>0, "internal buffer size must be greater than 0");
+ const CLAM::TData * audioBuffer = so.GetBuffer().GetPtr();
+ for (unsigned i=0; i<port.mBufferSize; i++)
+ port.mFloatBuffer[i] = audioBuffer[i];
+ in->Consume();
+ }
+
return true;
}
-void AudioSink::SetExternalBuffer( float* buf, unsigned nframes)
+void AudioSink::SetExternalBuffer(float* buf, unsigned nframes, unsigned index)
{
- mFloatBuffer = buf;
- mBufferSize = nframes;
- mDoubleBuffer = 0;
- mIn.SetSize(nframes);
- mIn.SetHop(nframes);
+ CLAM_ASSERT(index < _ports.size(), "AudioInPort index out of range");
+ Port& port = _ports[index];
+ port.mAudioIn->SetSize(nframes);
+ port.mAudioIn->SetHop(nframes);
+ port.mFloatBuffer = buf;
+ port.mBufferSize = nframes;
+ port.mDoubleBuffer = 0;
+
}
-void AudioSink::SetExternalBuffer( double* buf, unsigned nframes)
+
+void AudioSink::SetExternalBuffer(double* buf, unsigned nframes, unsigned index)
{
- mDoubleBuffer = buf;
- mBufferSize = nframes;
- mFloatBuffer = 0;
- mIn.SetSize(nframes);
- mIn.SetHop(nframes);
+ CLAM_ASSERT(index < _ports.size(), "AudioInPort index out of range");
+ Port& port = _ports[index];
+ port.mAudioIn->SetSize(nframes);
+ port.mAudioIn->SetHop(nframes);
+ port.mDoubleBuffer = buf;
+ port.mBufferSize = nframes;
+ port.mFloatBuffer = 0;
}
+
+void AudioSink::SetExternalBuffer(float* buf, unsigned nframes)
+{
+ CLAM_ASSERT(1 == _ports.size(), "AudioInPort index out of range");
+ Port& port = _ports[0];
+ port.mAudioIn->SetSize(nframes);
+ port.mAudioIn->SetHop(nframes);
+ port.mFloatBuffer = buf;
+ port.mBufferSize = nframes;
+ port.mDoubleBuffer = 0;
+}
+
+void AudioSink::SetExternalBuffer(double* buf, unsigned nframes)
+{
+ CLAM_ASSERT(1 == _ports.size(), "AudioInPort index out of range");
+ Port& port = _ports[0];
+ port.mAudioIn->SetSize(nframes);
+ port.mAudioIn->SetHop(nframes);
+ port.mDoubleBuffer = buf;
+ port.mBufferSize = nframes;
+ port.mFloatBuffer = 0;
+}
+
} //namespace CLAM
Index: Processing/AudioSource.hxx
===================================================================
--- Processing/AudioSource.hxx (revision 13150)
+++ Processing/AudioSource.hxx (working copy)
@@ -4,41 +4,142 @@
#include "Processing.hxx"
#include "AudioOutPort.hxx"
+#include <sstream>
+
namespace CLAM
{
- class AudioSource : public Processing
- {
- private:
- AudioOutPort mOut;
- const float* mFloatBuffer;
- const double* mDoubleBuffer;
- unsigned mBufferSize;
- public:
- AudioSource(const ProcessingConfig & conf=Config())
- : mOut("AudioOut",this)
- , mFloatBuffer(0)
- , mDoubleBuffer(0)
- , mBufferSize(0)
- {
- //After being dropped it is ready to run as it does not need any configuration at all
- SetExecState(Ready);
- }
+ class AudioSource : public Processing
+ {
+ public:
+ struct Port
+ {
+ const float* mFloatBuffer;
+ const double* mDoubleBuffer;
+ unsigned mBufferSize;
+ AudioOutPort* mAudioOut;
- void SetFrameAndHopSize(const int val)
- {
- mOut.SetSize(val);
- mOut.SetHop(val);
- }
-
- void SetExternalBuffer(const float* buf, unsigned nframes );
- void SetExternalBuffer(const double* buf, unsigned nframes );
+ Port() {}
- bool Do();
-
- const char* GetClassName() const { return "AudioSource";}
+ explicit Port(AudioOutPort* p)
+ : mFloatBuffer(0), mDoubleBuffer(0), mBufferSize(0), mAudioOut(p)
+ {
+ }
+ };
+ typedef std::vector<Port> Ports;
- };
+ private:
+ class Config : public ProcessingConfig
+ {
+ DYNAMIC_TYPE_USING_INTERFACE( Config, 1, ProcessingConfig );
+ DYN_ATTRIBUTE( 0, public, int, NSources);
+ protected:
+ void DefaultInit()
+ {
+ AddAll();
+ UpdateData();
+ SetNSources(1);
+ };
+ void LoadFrom(Storage & storage)
+ {
+ ProcessingConfig::LoadFrom(storage);
+ if (not HasNSources())
+ {
+ AddNSources();
+ UpdateData();
+ SetNSources(1);
+ }
+ }
+ };
+
+ private:
+ Config _config;
+ Ports _ports;
+
+ public:
+ AudioSource(const ProcessingConfig & config=Config())
+ {
+ //After being dropped it is ready to run as it does not need any configuration at all
+ //SetExecState(Ready);
+ Configure( config );
+ }
+
+ ~AudioSource()
+ {
+ for (unsigned port = 0; port < _ports.size(); ++port)
+ delete _ports[port].mAudioOut;
+ }
+
+ void SetFrameAndHopSize(const int val)
+ {
+ CLAM_ASSERT(1 == _ports.size(), "AudioOutPort out of range");
+ Port& port = _ports[0];
+ port.mAudioOut->SetSize(val);
+ port.mAudioOut->SetHop(val);
+ }
+
+ void SetFrameAndHopSize(const int val, unsigned index)
+ {
+ CLAM_ASSERT(index < _ports.size(), "AudioOutPort index out of range");
+ Port& port = _ports[index];
+ port.mAudioOut->SetSize(val);
+ port.mAudioOut->SetHop(val);
+ }
+
+ void SetExternalBuffer(const float* buf, unsigned nframes, unsigned index);
+ void SetExternalBuffer(const double* buf, unsigned nframes, unsigned index);
+
+ void SetExternalBuffer(const float* buf, unsigned nframes);
+ void SetExternalBuffer(const double* buf, unsigned nframes);
+
+ bool Do();
+
+ const char* GetClassName() const { return "AudioSource";}
+
+ const ProcessingConfig & GetConfig() const
+ {
+ return _config;
+ }
+
+ bool ConcreteConfigure(const ProcessingConfig& config)
+ {
+ CopyAsConcreteConfig(_config, config);
+ unsigned sources = _config.GetNSources();
+
+ ResizePorts(sources);
+
+ return true;
+ }
+
+ Ports & GetPorts() { return _ports; }
+
+ private:
+ void ResizePorts(unsigned sources)
+ {
+ if (sources == _ports.size())
+ return;
+
+ if (sources < _ports.size())
+ {
+ for (unsigned port = sources; port < _ports.size(); ++port)
+ delete _ports[port].mAudioOut;
+
+ _ports.resize(sources);
+ }
+
+ if (sources > _ports.size())
+ {
+ for (unsigned port = _ports.size(); port < sources; ++port)
+ _ports.push_back(Port(new AudioOutPort(Portname(port), this)));
+ }
+ }
+
+ std::string const Portname(unsigned port) const
+ {
+ std::ostringstream os;
+ os << port;
+ return os.str();
+ }
+ };
} //namespace CLAM
#endif
-
Index: Processing/AudioSink.hxx
===================================================================
--- Processing/AudioSink.hxx (revision 13150)
+++ Processing/AudioSink.hxx (working copy)
@@ -4,35 +4,90 @@
#include "Processing.hxx"
#include "AudioInPort.hxx"
+#include <sstream>
+
namespace CLAM
{
class AudioSink : public Processing
{
+ public:
+ struct Port
+ {
+ float* mFloatBuffer;
+ double* mDoubleBuffer;
+ unsigned mBufferSize;
+ AudioInPort* mAudioIn;
+
+ Port(){} //resize needs a default constructor
+
+ explicit Port(AudioInPort* p)
+ : mFloatBuffer(0), mDoubleBuffer(0), mBufferSize(0), mAudioIn(p)
+ {
+ }
+ };
+ typedef std::vector<Port> Ports;
+
+ private:
+ class Config : public ProcessingConfig
+ {
+ DYNAMIC_TYPE_USING_INTERFACE( Config, 1, ProcessingConfig );
+ DYN_ATTRIBUTE( 0, public, int, NSinks);
+ protected:
+ void DefaultInit()
+ {
+ AddAll();
+ UpdateData();
+ SetNSinks(1);
+ };
+ void LoadFrom(Storage & storage)
+ {
+ ProcessingConfig::LoadFrom(storage);
+ if (not HasNSinks())
+ {
+ AddNSinks();
+ UpdateData();
+ SetNSinks(1);
+ }
+ }
+ };
+
private:
- AudioInPort mIn;
- float* mFloatBuffer;
- double* mDoubleBuffer;
- unsigned mBufferSize;
+ Config _config;
+ Ports _ports;
public:
- AudioSink(const ProcessingConfig & conf=Config())
- : mIn("AudioIn",this)
- , mFloatBuffer(0)
- , mDoubleBuffer(0)
- , mBufferSize(0)
+ AudioSink(const ProcessingConfig & config=Config())
{
//After being dropped it is ready to run as it does not need any configuration at all
- SetExecState(Ready);
+ //SetExecState(Ready);
+ Configure( config );
}
+ ~AudioSink()
+ {
+ for (unsigned port = 0; port < _ports.size(); ++port)
+ delete _ports[port].mAudioIn;
+ }
+
/// @deprecated Delegated to SetExternalBuffer
- void SetFrameAndHopSize(const int val)
- {
- mIn.SetSize(val);
- mIn.SetHop(val);
- }
+ void SetFrameAndHopSize(const int val)
+ {
+ CLAM_ASSERT(1 == _ports.size(), "AudioInPort index out of range");
+ Port& port = _ports[0];
+ port.mAudioIn->SetSize(val);
+ port.mAudioIn->SetHop(val);
+ }
- ~AudioSink() {}
+ void SetFrameAndHopSize(const int val, unsigned index)
+ {
+ CLAM_ASSERT(index < _ports.size(), "AudioInPort index out of range");
+ Port& port = _ports[index];
+ port.mAudioIn->SetSize(val);
+ port.mAudioIn->SetHop(val);
+ }
+
+ void SetExternalBuffer(float* buf, unsigned nframes, unsigned index);
+ void SetExternalBuffer(double* buf, unsigned nframes, unsigned index);
void SetExternalBuffer(float* buf, unsigned nframes );
void SetExternalBuffer(double* buf, unsigned nframes );
@@ -41,6 +96,52 @@
const char* GetClassName() const { return "AudioSink";}
+ const ProcessingConfig & GetConfig() const
+ {
+ return _config;
+ }
+
+ bool ConcreteConfigure(const ProcessingConfig& config)
+ {
+ CopyAsConcreteConfig(_config, config);
+ unsigned sinks = _config.GetNSinks();
+
+ ResizePorts(sinks);
+
+ return true;
+ }
+
+ Ports& GetPorts() { return _ports; }
+
+ private:
+ void ResizePorts(unsigned sinks)
+ {
+ if (sinks == _ports.size())
+ return;
+
+ if (sinks < _ports.size())
+ {
+ for (unsigned port = sinks; port < _ports.size(); ++port)
+ delete _ports[port].mAudioIn;
+
+ _ports.resize(sinks);
+ }
+
+ if (sinks > _ports.size())
+ {
+ for (unsigned port = _ports.size(); port < sinks; ++port)
+ _ports.push_back(Port(new AudioInPort(Portname(port), this)));
+ }
+ }
+
+ std::string const Portname(unsigned port) const
+ {
+ std::ostringstream os;
+ os << port;
+ return os.str();
+ }
+
+
};
} //namespace CLAM
Index: UnitTests/FlowControlTests/TestsCallbackBasedNetwork.cxx
===================================================================
--- UnitTests/FlowControlTests/TestsCallbackBasedNetwork.cxx (revision 13150)
+++ UnitTests/FlowControlTests/TestsCallbackBasedNetwork.cxx (working copy)
@@ -211,7 +211,7 @@
CLAM::AudioSink * sink = new CLAM::AudioSink;
_network.AddProcessing("Source", source);
_network.AddProcessing("Sink", sink);
- _network.ConnectPorts("Source.AudioOut", "Sink.AudioIn");
+ _network.ConnectPorts("Source.0", "Sink.0");
_network.Start();
source->SetExternalBuffer(_inFloat, 2);
sink->SetExternalBuffer(_outFloat, 2);
@@ -240,8 +240,8 @@
_network.AddProcessing("Source", source);
_network.AddProcessing("Sink", sink);
_network.AddProcessing("Filter", filter);
- _network.ConnectPorts("Source.AudioOut", "Filter.in");
- _network.ConnectPorts("Filter.out", "Sink.AudioIn");
+ _network.ConnectPorts("Source.0", "Filter.in");
+ _network.ConnectPorts("Filter.out", "Sink.0");
_network.Start();
source->SetExternalBuffer(_inFloat, 2);
sink->SetExternalBuffer(_outFloat, 2);
@@ -257,8 +257,8 @@
_network.AddProcessing("Source", source);
_network.AddProcessing("Sink", sink);
_network.AddProcessing("Filter", filter);
- _network.ConnectPorts("Source.AudioOut", "Filter.in");
- _network.ConnectPorts("Filter.out", "Sink.AudioIn");
+ _network.ConnectPorts("Source.0", "Filter.in");
+ _network.ConnectPorts("Filter.out", "Sink.0");
_network.Start();
source->SetExternalBuffer(_inFloat, 2);
sink->SetExternalBuffer(_outFloat, 2);
@@ -274,8 +274,8 @@
_network.AddProcessing("Source", source);
_network.AddProcessing("Sink", sink);
_network.AddProcessing("Filter", filter);
- _network.ConnectPorts("Source.AudioOut", "Filter.in");
- _network.ConnectPorts("Filter.out", "Sink.AudioIn");
+ _network.ConnectPorts("Source.0", "Filter.in");
+ _network.ConnectPorts("Filter.out", "Sink.0");
_network.Start();
source->SetExternalBuffer(_inFloat, 2);
sink->SetExternalBuffer(_outFloat, 2);
@@ -303,8 +303,8 @@
_network.AddProcessing("Source", source);
_network.AddProcessing("Sink", sink);
_network.AddProcessing("Filter", filter);
- _network.ConnectPorts("Source.AudioOut", "Filter.in");
- _network.ConnectPorts("Filter.out", "Sink.AudioIn");
+ _network.ConnectPorts("Source.0", "Filter.in");
+ _network.ConnectPorts("Filter.out", "Sink.0");
_network.Start();
source->SetExternalBuffer(_inFloat, 2);
sink->SetExternalBuffer(_outFloat, 2);
@@ -335,8 +335,8 @@
_network.AddProcessing("Source", source);
_network.AddProcessing("Sink", sink);
_network.AddProcessing("Filter", filter);
- _network.ConnectPorts("Source.AudioOut", "Filter.in");
- _network.ConnectPorts("Source.AudioOut", "Sink.AudioIn");
+ _network.ConnectPorts("Source.0", "Filter.in");
+ _network.ConnectPorts("Source.0", "Sink.0");
_network.Start();
for (int i=0; i<iterations; i++)
{
@@ -356,8 +356,8 @@
_network.AddProcessing("Source", source);
_network.AddProcessing("Sink", sink);
_network.AddProcessing("Filter", filter);
- _network.ConnectPorts("Source.AudioOut", "Filter.in");
- _network.ConnectPorts("Source.AudioOut", "Sink.AudioIn");
+ _network.ConnectPorts("Source.0", "Filter.in");
+ _network.ConnectPorts("Source.0", "Sink.0");
_network.Start();
source->SetExternalBuffer(_inFloat, callbackStep);
sink->SetExternalBuffer(_outFloat, callbackStep);
@@ -371,7 +371,7 @@
DummyGenerator * generator = new DummyGenerator(3);
_network.AddProcessing("Sink", sink);
_network.AddProcessing("Generator", generator);
- _network.ConnectPorts("Generator.out", "Sink.AudioIn");
+ _network.ConnectPorts("Generator.out", "Sink.0");
_network.Start();
sink->SetExternalBuffer(_outFloat, 4);
_network.Do();
@@ -387,7 +387,7 @@
_network.AddProcessing("Source", source);
_network.AddProcessing("Sink", sink);
_network.AddProcessing("IsolatedGenerator", isolated);
- _network.ConnectPorts("Source.AudioOut", "Sink.AudioIn");
+ _network.ConnectPorts("Source.0", "Sink.0");
_network.Start();
sink->SetExternalBuffer(_outFloat, 4);
source->SetExternalBuffer(_inFloat, 4);
Index: FunctionalTests/ProcessingTests/TestStreamingSMSAnalysisSynthesis.cxx
===================================================================
--- FunctionalTests/ProcessingTests/TestStreamingSMSAnalysisSynthesis.cxx (revision 13145)
+++ FunctionalTests/ProcessingTests/TestStreamingSMSAnalysisSynthesis.cxx (working copy)
@@ -196,10 +196,10 @@
net.AddProcessing( "Analysis", new CLAM::SMSAnalysisCore );
net.AddProcessing( "Synthesis", new CLAM::SMSSynthesis );
- net.ConnectPorts("Source.AudioOut", "Analysis.Input Audio");
+ net.ConnectPorts("Source.0", "Analysis.Input Audio");
net.ConnectPorts("Analysis.Sinusoidal Peaks", "Synthesis.InputSinPeaks");
net.ConnectPorts("Analysis.Residual Spectrum", "Synthesis.InputResSpectrum");
- net.ConnectPorts("Synthesis.OutputAudio", "Sink.AudioIn");
+ net.ConnectPorts("Synthesis.OutputAudio", "Sink.0");
net.ConfigureProcessing("Analysis", helperAnalysisConfigInstance() );
net.ConfigureProcessing("Synthesis", helperSynthesisConfigInstance() );
renameConnector AudioSource outport "AudioOut" 0
renameConnector AudioSink inport "AudioIn" 0
_______________________________________________
CLAM mailing list
[email protected]
http://clam.iua.upf.edu