CLAM-Development  1.4.0
Processing.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 
23 #include "Processing.hxx"
24 #include "ProcessingComposite.hxx"
25 #include "TopLevelProcessing.hxx"
26 #include "InPort.hxx"
27 #include "OutPort.hxx"
28 #include "InControl.hxx"
29 #include "OutControl.hxx"
30 #include "Network.hxx"
31 
32 #include <cstring>
33 #include <string>
34 
35 
36 namespace CLAM
37 {
39  Processing & sender, const std::string & outPortName,
40  Processing & receiver, const std::string & inPortName )
41  {
42  OutPortBase & out = sender.GetOutPort(outPortName);
43  InPortBase & in = receiver.GetInPort(inPortName);
44  out.ConnectToIn(in);
45  }
46 
48  Processing & sender, const std::string & outControlName,
49  Processing & receiver, const std::string & inControlName )
50  {
51  OutControlBase & out = sender.GetOutControl(outControlName);
52  InControlBase & in = receiver.GetInControl(inControlName);
53  out.AddLink(in);
54  }
55 
57  Processing & sender, unsigned outPortNumber,
58  Processing & receiver, unsigned inPortNumber )
59  {
60  OutPortBase & out = sender.GetOutPort(outPortNumber);
61  InPortBase & in = receiver.GetInPort(inPortNumber);
62  out.ConnectToIn(in);
63  }
64 
66  Processing & sender, unsigned outControlNumber,
67  Processing & receiver, unsigned inControlNumber )
68  {
69  OutControlBase & out = sender.GetOutControl(outControlNumber);
70  InControlBase & in = receiver.GetInControl(inControlNumber);
71  out.AddLink(in);
72  }
73 
75  Processing & sender, unsigned outPortNumber,
76  InPortBase & in )
77  {
78  OutPortBase & out = sender.GetOutPort(outPortNumber);
79  out.ConnectToIn(in);
80  }
81 
83  OutPortBase & out,
84  Processing & receiver, unsigned inPortNumber )
85  {
86  InPortBase & in = receiver.GetInPort(inPortNumber);
87  out.ConnectToIn(in);
88  }
89 
91  Processing & sender, std::string outPortName,
92  InPortBase & in )
93  {
94  OutPortBase & out = sender.GetOutPort(outPortName);
95  out.ConnectToIn(in);
96  }
97 
99  OutPortBase & out,
100  Processing & receiver, std::string inPortName )
101  {
102  InPortBase & in = receiver.GetInPort(inPortName);
103  out.ConnectToIn(in);
104  }
105 
106  void SendFloatToInControl(Processing & receiver, const std::string & inControlName, float value){
107  InControlBase & in = receiver.GetInControl(inControlName);
108  FloatOutControl controlSender("tmpOutControl");
109  CLAM_ASSERT(controlSender.IsLinkable(in), "GetFloatFromInControl: the control was not a Float control");
110  controlSender.AddLink(in);
111  controlSender.SendControl(value);
112  }
113 
114  void SendFloatToInControl(Processing & receiver, int inControlIndex, float value){
115  InControlBase & in = receiver.GetInControl(inControlIndex);
116  FloatOutControl controlSender("tmpOutControl");
117  CLAM_ASSERT(controlSender.IsLinkable(in), "GetFloatFromInControl: the control was not a Float control");
118  controlSender.AddLink(in);
119  controlSender.SendControl(value);
120  }
121 
122  void SendFloatToOutControl(Processing & sender, const std::string & inControlName, float value){
123  FloatOutControl * out = dynamic_cast<FloatOutControl*>(&(sender.GetOutControl(inControlName)));
124  CLAM_ASSERT(out, "SendFloatToOutControl: the control was not a Float control");
125  out->SendControl(value);
126  }
127 
128  void SendFloatToOutControl(Processing & sender, int outControlIndex, float value){
129  FloatOutControl * out = dynamic_cast<FloatOutControl*>(&(sender.GetOutControl(outControlIndex)));
130  CLAM_ASSERT(out, "SendFloatToOutControl: the control was not a Float control");
131  out->SendControl(value);
132  }
133 
134  float GetFloatFromInControl(Processing & proc, const std::string & inControlName){
135  FloatInControl * in = dynamic_cast<FloatInControl*>(&(proc.GetInControl(inControlName)));
136  CLAM_ASSERT(in, "GetFloatFromInControl: the control was not a Float control");
137  return in->GetLastValue();
138  }
139 
140  float GetFloatFromInControl(Processing & proc, int inControlIndex){
141  FloatInControl * in = dynamic_cast<FloatInControl*>(&(proc.GetInControl(inControlIndex)));
142  CLAM_ASSERT(in, "GetFloatFromInControl: the control was not a Float control");
143  return in->GetLastValue();
144  }
145 
147  : mpParent(0)
148  , _network(0)
149  , _execState(Unconfigured)
150  {
151  }
152 
154  {
155  CLAM_ASSERT(!IsRunning(), "Configuring an already running Processing.");
156  _configErrorMessage = "";
157 // if (!mpParent) //TODO remove
158 // TopLevelProcessing::GetInstance().Insert(*this);
159  _execState = Unconfigured;
160  try
161  {
162  if (!ConcreteConfigure(c))
163  {
164  if (_configErrorMessage=="")
165  _configErrorMessage = "Configuration failed.";
166  return false;
167  }
168  }
169  catch( ErrProcessingObj& error )
170  {
171  _configErrorMessage += "Exception thrown during ConcreteConfigure:\n";
172  _configErrorMessage += error.what();
173  _configErrorMessage += "\n";
174  _configErrorMessage += "Configuration failed.";
175  return false;
176  }
177  _execState = Ready;
178  _configErrorMessage="Ready to be started";
179  return true;
180  }
181 
183  {
184  if ( mpParent )
185  mpParent->Remove(*this);
186  }
187 
188  void Processing::Start(void)
189  {
190  CLAM_ASSERT(!IsRunning(), "Starting an already started processing");
191  CLAM_ASSERT(IsConfigured(), "Starting an unconfigured processing");
192  try {
193  if (ConcreteStart())
194  _execState = Running;
195  }
196  catch (ErrProcessingObj &e) {
197  _configErrorMessage += "Exception thrown while starting.\n";
198  _configErrorMessage += e.what();
199  }
200  }
201 
202  void Processing::Stop(void)
203  {
204  CLAM_ASSERT(IsRunning(), "Stop(): Object not running." );
205  try {
206  if(ConcreteStop())
207  _execState = Ready;
208  }
209  catch (ErrProcessingObj &e) {
210  _configErrorMessage += "Exception thrown while stoping.\n";
211  _configErrorMessage += e.what();
212  }
213  }
215  {
216  if (_network)
217  return _network->BackendBufferSize();
218  //TODO: 1- inherit the buffer size on embeded processings without linked network
219  //TODO: 2- resolve the multiple configuration instances, that makes the first ConcreteConfigure (on XML loading) print this message
220  //std::cout<<"Warning: no linked network, using hardcoded backend buffer size (1024) on processing "<<GetClassName()<<std::endl;
221  return 1024;
222  }
224  {
225  return _network? _network->BackendSampleRate() : 44100;
226  }
227 
229  {
230  mOutPortRegistry.ProcessingInterface_Register(out);
231  }
233  {
234  mInPortRegistry.ProcessingInterface_Register(in);
235  }
236 
238  {
239  mOutControlRegistry.ProcessingInterface_Register(out);
240  }
242  {
243  mInControlRegistry.ProcessingInterface_Register(in);
244  }
246  {
247  ProcessingComposite * composite;
248  if (!parent)
249  composite = &(TopLevelProcessing::GetInstance());
250  else
251  composite = dynamic_cast<ProcessingComposite*>(parent);
252  CLAM_ASSERT(composite, "Setting a non ProcessingComposite as Parent");
253 
254  if (mpParent==composite)
255  return;
256 
257  if (mpParent)
258  mpParent->Remove(*this);
259  mpParent=composite;
260  mpParent->Insert(*this);
261  }
262 
264  {
265  _network=network;
266  }
267  bool Processing::AddConfigErrorMessage( const std::string& msg )
268  {
269  _configErrorMessage += msg;
270  // For convenience, so you can report and exit in one line from ConcreteConfigure
271  // return AddConfigErrorMessage("My error");
272  return false;
273  }
274 
276  {
277  if(!IsRunning())
278  {
279  std::cerr << "Cannot execute '" << GetClassName() << "' because not Running!" << std::endl;
280  return false;
281  }
282 // std::cerr<< "inports ready? " << GetInPorts().AreReadyForReading() << std::endl;
283 // std::cerr << "outports ready? " << GetOutPorts().AreReadyForWriting() << std::endl;
285  }
287  {
288  // TODO: Not yet implemented
289  /*
290  for (unsigned i=0; i<GetNOutPorts(); i++)
291  GetOutPort(i).Produce();
292  for (unsigned i=0; i<GetNInPorts(); i++)
293  GetInPort(i).Consume();
294  */
295 
296  }
297 
299  {
300  static NullProcessingConfig nullConfig;
301  return nullConfig;
302  }
303  std::string Processing::GetExecStateString() const
304  {
305  switch (_execState)
306  {
307  case Unconfigured:
308  return "Unconfigured";
309  case Ready:
310  return "Ready";
311  case Running:
312  return "Running";
313  }
314  CLAM_ASSERT(false, "Unknown processing exec state found");
315  return "INTERNAL ERROR";
316  }
317 
318 
319 
320 };//namespace CLAM
321