1 /* SpiralSound
2 * Copyleft (C) 2001 David Griffiths <dave@pawfal.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include <stdio.h>
20 #include <limits.h>
21 #include <math.h>
22
23 #include "JackPlugin.h"
24 #include "JackPluginGUI.h"
25 #include "SpiralIcon.xpm"
26
27 using namespace std;
28
29 int JackClient::JackProcessInstanceID = -1;
30 int JackPlugin::JackInstanceCount = 0;
31
32 /////////////////////////////////////////////////////////////////////////////////////////////
JackProcess_i(jack_nframes_t nframes)33 inline void JackClient::JackProcess_i(jack_nframes_t nframes)
34 {
35 SetBufferSize(nframes);
36
37 for (int n=0; n<GetJackInputCount(); n++)
38 {
39 if (jack_port_connected(m_InputPortMap[n]->Port))
40 {
41 sample_t *in = (sample_t *) jack_port_get_buffer(m_InputPortMap[n]->Port, nframes);
42 memcpy (m_InputPortMap[n]->Buf, in, sizeof (sample_t) * GetBufferSize());
43 }
44 }
45
46 for (int n=0; n<GetJackOutputCount(); n++)
47 {
48 if (jack_port_connected(m_OutputPortMap[n]->Port))
49 {
50 if (m_OutputPortMap[n]->Buf)
51 {
52 sample_t *out = (sample_t *) jack_port_get_buffer(m_OutputPortMap[n]->Port, nframes);
53 memcpy (out, m_OutputPortMap[n]->Buf, sizeof (sample_t) * GetBufferSize());
54 }
55 else // no output availible, clear
56 {
57 sample_t *out = (sample_t *) jack_port_get_buffer(m_OutputPortMap[n]->Port, nframes);
58 memset (out, 0, sizeof (sample_t) * GetBufferSize());
59 }
60 }
61 }
62
63 if (RunCallback&&RunContext)
64 {
65 if (JackProcessInstanceID==-1)
66 JackProcessInstanceID = m_JackInstanceID;
67
68 if (JackProcessInstanceID==m_JackInstanceID)
69 RunCallback(RunContext,true);
70 }
71 }
72
73 /////////////////////////////////////////////////////////////////////////////////////////////
74
SampleRateChange_i(jack_nframes_t nframes)75 inline void JackClient::SampleRateChange_i(jack_nframes_t nframes)
76 {
77 SetSampleRate(nframes);
78 }
79
80 /////////////////////////////////////////////////////////////////////////////////////////////
81
JackShutdown_i()82 inline void JackClient::JackShutdown_i()
83 {
84 cerr<<"Shutdown"<<endl;
85
86 SetAttached(false);
87
88 if (JackProcessInstanceID==m_JackInstanceID)
89 JackProcessInstanceID = -1;
90
91 // tells ssm to go back to non callback mode
92 RunCallback(RunContext, false);
93 }
94
95 ///////////////////////////////////////////////////////
96
JackClient()97 JackClient::JackClient()
98 {
99 m_JackInstanceID = 0;
100 m_Attached = false;
101 m_SampleRate = 0;
102 m_BufferSize = 0;
103 m_JackInputCount = 4;
104 m_JackOutputCount = 4;
105 m_Client=NULL;
106 }
107
108 /////////////////////////////////////////////////////////////////////////////////////////////
109
~JackClient()110 JackClient::~JackClient()
111 {
112 if (IsAttached()) Detach();
113 }
114
115 /////////////////////////////////////////////////////////////////////////////////////////////
116
AddInputPort(int NewPortNumber)117 void JackClient::AddInputPort(int NewPortNumber)
118 {
119 char Name[256];
120 JackPort *NewPort;
121
122 if (!(m_Client)) return;
123
124 NewPort = new JackPort;
125
126 sprintf(Name,"In%d", NewPortNumber);
127
128 NewPort->PortNo = NewPortNumber;
129 NewPort->Name=Name;
130 NewPort->Buf=NULL;
131 NewPort->Port = jack_port_register (m_Client, Name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
132
133 m_InputPortMap[NewPortNumber]=NewPort;
134 }
135
AddOutputPort(int NewPortNumber)136 void JackClient::AddOutputPort(int NewPortNumber)
137 {
138 char Name[256];
139 JackPort *NewPort;
140
141 if (!(m_Client)) return;
142
143 NewPort = new JackPort;
144
145 sprintf(Name,"Out%d", NewPortNumber);
146
147 NewPort->PortNo = NewPortNumber;
148 NewPort->Name=Name;
149 NewPort->Buf=NULL;
150 NewPort->Port = jack_port_register (m_Client, Name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
151
152 m_OutputPortMap[NewPortNumber]=NewPort;
153 }
154
RemoveInputPort(int PortNumber)155 void JackClient::RemoveInputPort(int PortNumber)
156 {
157 char Name[256];
158 JackPort *OldPort;
159
160 if (!(m_Client)) return;
161
162 OldPort = m_InputPortMap[PortNumber];
163 m_InputPortMap[PortNumber] = NULL;
164 jack_port_unregister (m_Client, OldPort->Port);
165 delete OldPort;
166 }
167
RemoveOutputPort(int PortNumber)168 void JackClient::RemoveOutputPort(int PortNumber)
169 {
170 char Name[256];
171 JackPort *OldPort;
172
173 if (!(m_Client)) return;
174
175 OldPort = m_OutputPortMap[PortNumber];
176 m_OutputPortMap[PortNumber] = NULL;
177 jack_port_unregister (m_Client, OldPort->Port);
178 delete OldPort;
179 }
180
Attach()181 bool JackClient::Attach()
182 {
183 char JackClientName[256];
184
185 if (m_Attached) return true;
186
187 sprintf(JackClientName,"SSM%d",GetJackInstanceID());
188 if (!(m_Client = jack_client_new(JackClientName)))
189 {
190 cerr<<"jack server not running?"<<endl;
191 return false;
192 }
193
194 jack_set_process_callback(m_Client, JackProcess, this);
195 jack_set_sample_rate_callback (m_Client, SampleRateChange, this);
196 jack_on_shutdown (m_Client, JackShutdown, this);
197
198 // create the ports
199 m_InputPortMap.clear();
200 for (int n=0; n<GetJackInputCount(); n++)
201 AddInputPort(n);
202
203 m_OutputPortMap.clear();
204 for (int n=0; n<GetJackOutputCount(); n++)
205 AddOutputPort(n);
206
207 // tell the JACK server that we are ready to roll
208 if (jack_activate (m_Client))
209 {
210 cerr<<"cannot activate client"<<endl;
211 return false;
212 }
213
214 m_Attached=true;
215
216 cerr<<"connected to jack..."<<endl;
217
218 return true;
219 }
220
221 /////////////////////////////////////////////////////////////////////////////////////////////
222
Detach()223 void JackClient::Detach()
224 {
225 if (m_Client)
226 {
227 cerr<<"Detaching from JACK"<<endl;
228 jack_client_close(m_Client);
229 m_Client=NULL;
230 m_Attached=false;
231 }
232
233 if (JackProcessInstanceID==m_JackInstanceID)
234 JackProcessInstanceID = -1;
235
236 // tells ssm to go back to non callback mode
237 RunCallback(RunContext, false);
238 }
239
240 /////////////////////////////////////////////////////////////////////////////////////////////
241
GetPortNames(vector<string> & InputNames,vector<string> & OutputNames)242 void JackClient::GetPortNames(vector<string> &InputNames, vector<string> &OutputNames)
243 {
244 InputNames.clear();
245 OutputNames.clear();
246
247 if (!m_Attached) return;
248
249 //Outputs first
250 const char **PortNameList=jack_get_ports(m_Client,NULL,NULL,JackPortIsOutput);
251
252 int n=0;
253 while(PortNameList[n]!=NULL)
254 {
255 OutputNames.push_back(PortNameList[n]);
256 n++;
257 }
258
259 delete PortNameList;
260
261 //Inputs second
262 PortNameList=jack_get_ports(m_Client,NULL,NULL,JackPortIsInput);
263
264 n=0;
265 while(PortNameList[n]!=NULL)
266 {
267 InputNames.push_back(PortNameList[n]);
268 n++;
269 }
270
271 delete PortNameList;
272 }
273
274 /////////////////////////////////////////////////////////////////////////////////////////////
275 // Input means input of SSM, so this connects jack sources to the plugin outputs
ConnectInput(int n,const string & JackPort)276 void JackClient::ConnectInput(int n, const string &JackPort)
277 {
278 if (!IsAttached()) return;
279
280 cerr<<"JackClient::ConnectInput: connecting source ["<<JackPort<<"] to dest ["<<m_InputPortMap[n]->Name<<"]"<<endl;
281
282 if (m_InputPortMap[n]->ConnectedTo!="")
283 {
284 if (jack_disconnect (m_Client, m_InputPortMap[n]->ConnectedTo.c_str(), jack_port_name(m_InputPortMap[n]->Port)))
285 cerr<<"JackClient::ConnectInput: cannot disconnect input port ["
286 <<m_InputPortMap[n]->ConnectedTo<<"] from ["<<m_InputPortMap[n]->Name<<"]"<<endl;
287 }
288
289 m_InputPortMap[n]->ConnectedTo = JackPort;
290
291 if (jack_connect (m_Client, JackPort.c_str(), jack_port_name(m_InputPortMap[n]->Port)))
292 cerr<<"JackClient::ConnectInput: cannot connect input port ["
293 <<JackPort<<"] to ["<<m_InputPortMap[n]->Name<<"]"<<endl;
294
295 m_InputPortMap[n]->Connected=true;
296 }
297
298 /////////////////////////////////////////////////////////////////////////////////////////////
299 // Output means output of SSM, so this connects plugin inputs to a jack destination
ConnectOutput(int n,const string & JackPort)300 void JackClient::ConnectOutput(int n, const string &JackPort)
301 {
302 if (!IsAttached()) return;
303 cerr<<"JackClient::ConnectOutput: connecting source ["<<m_OutputPortMap[n]->Name<<"] to dest ["<<JackPort<<"]"<<endl;
304
305 if (m_OutputPortMap[n]->ConnectedTo!="")
306 {
307 if (jack_disconnect (m_Client, jack_port_name(m_OutputPortMap[n]->Port), m_OutputPortMap[n]->ConnectedTo.c_str()))
308 cerr<<"JackClient::ConnectOutput: cannot disconnect output port ["
309 <<m_OutputPortMap[n]->ConnectedTo<<"] from ["<<m_OutputPortMap[n]->Name<<"]"<<endl;
310 }
311
312 m_OutputPortMap[n]->ConnectedTo = JackPort;
313 if (jack_connect (m_Client, jack_port_name(m_OutputPortMap[n]->Port), JackPort.c_str()))
314 cerr<<"JackClient::ConnectOutput: cannot connect output port ["
315 <<m_OutputPortMap[n]->Name<<"] to ["<<JackPort<<"]"<<endl;
316 m_OutputPortMap[n]->Connected=true;
317 }
318
319 /////////////////////////////////////////////////////////////////////////////////////////////
320 // Input means input of SSM, so this connects jack sources to the plugin outputs
DisconnectInput(int n)321 void JackClient::DisconnectInput(int n)
322 {
323 if (!IsAttached()) return;
324 cerr<<"JackClient::DisconnectInput: Disconnecting input "<<n<<endl;
325
326 if (m_InputPortMap[n]->ConnectedTo!="")
327 {
328 if (jack_disconnect (m_Client, m_InputPortMap[n]->ConnectedTo.c_str(), jack_port_name(m_InputPortMap[n]->Port)))
329 cerr<<"JackClient::ConnectInput: cannot disconnect input port ["
330 <<m_InputPortMap[n]->ConnectedTo<<"] from ["<<m_InputPortMap[n]->Name<<"]"<<endl;
331 }
332
333 m_InputPortMap[n]->Connected=false;
334 }
335
336 /////////////////////////////////////////////////////////////////////////////////////////////
337 // Output means output of SSM, so this connects plugin inputs to a jack destination
DisconnectOutput(int n)338 void JackClient::DisconnectOutput(int n)
339 {
340 if (!IsAttached()) return;
341 cerr<<"JackClient::DisconnectInput: Disconnecting input "<<n<<endl;
342
343 if (m_OutputPortMap[n]->ConnectedTo!="")
344 {
345 if (jack_disconnect (m_Client, jack_port_name(m_OutputPortMap[n]->Port), m_OutputPortMap[n]->ConnectedTo.c_str()))
346 cerr<<"JackClient::ConnectOutput: cannot disconnect output port ["
347 <<m_OutputPortMap[n]->ConnectedTo<<"] from ["<<m_OutputPortMap[n]->Name<<"]"<<endl;
348 }
349
350 m_OutputPortMap[n]->Connected=false;
351 }
352 /////////////////////////////////////////////////////////////////////////////////////////////
353
SetInputBuf(int ID,float * s)354 void JackClient::SetInputBuf(int ID, float* s)
355 {
356 if(m_InputPortMap.find(ID)!=m_InputPortMap.end()) m_InputPortMap[ID]->Buf=s;
357 }
358
359 /////////////////////////////////////////////////////////////////////////////////////////////
360
SetOutputBuf(int ID,float * s)361 void JackClient::SetOutputBuf(int ID, float* s)
362 {
363 if(m_OutputPortMap.find(ID)!=m_OutputPortMap.end()) m_OutputPortMap[ID]->Buf=s;
364 }
365
366 /////////////////////////////////////////////////////////////////////////////////////////////
367
368 extern "C" {
SpiralPlugin_CreateInstance()369 SpiralPlugin* SpiralPlugin_CreateInstance()
370 {
371 return new JackPlugin;
372 }
373
SpiralPlugin_GetIcon()374 char** SpiralPlugin_GetIcon()
375 {
376 return SpiralIcon_xpm;
377 }
378
SpiralPlugin_GetID()379 int SpiralPlugin_GetID()
380 {
381 return 31;
382 }
383
SpiralPlugin_GetGroupName()384 string SpiralPlugin_GetGroupName()
385 {
386 return "InputOutput";
387 }
388 }
389
390 ///////////////////////////////////////////////////////
391
JackPlugin()392 JackPlugin::JackPlugin() :
393 m_UpdateNames(false),
394 m_Connected(false)
395 {
396 m_JackClient=new JackClient;
397
398 //clunky way to ensure unique JackID - JackInstanceCount is never dec
399 //so new JackInstances per session always get a higher number even on
400 //reload and new Patch
401
402 m_JackInstanceID = JackInstanceCount;
403 JackInstanceCount++;
404
405 m_JackClient->SetJackInstanceID(m_JackInstanceID);
406
407 // we are an output
408 m_IsTerminal = true;
409
410 m_Version = 2;
411
412 m_PluginInfo.Name="Jack";
413 m_PluginInfo.Width=225;
414 m_PluginInfo.Height=230;
415 m_PluginInfo.NumInputs=0;
416 m_PluginInfo.NumOutputs=0;
417
418 m_PluginInfo.PortTips.clear();
419
420 m_PluginInfo.NumInputs = m_JackClient->GetJackOutputCount();
421 m_GUIArgs.NumInputs = m_PluginInfo.NumInputs;
422
423 for (int n=0; n<m_JackClient->GetJackInputCount(); n++)
424 {
425 char Temp[256];
426 sprintf(Temp,"SSM Input %d",n);
427 m_PluginInfo.PortTips.push_back(Temp);
428 }
429
430 m_PluginInfo.NumOutputs = m_JackClient->GetJackOutputCount();
431 m_GUIArgs.NumOutputs = m_PluginInfo.NumOutputs;
432
433 for (int n=0; n<m_JackClient->GetJackOutputCount(); n++)
434 {
435 char Temp[256];
436 sprintf(Temp,"SSM Output %d",n);
437 m_PluginInfo.PortTips.push_back(Temp);
438 }
439
440 m_AudioCH->Register("NumInputs",&m_GUIArgs.NumInputs);
441 m_AudioCH->Register("NumOutputs",&m_GUIArgs.NumOutputs);
442 m_AudioCH->RegisterData("Port",ChannelHandler::INPUT,&m_GUIArgs.Port,sizeof(m_GUIArgs.Port));
443 m_AudioCH->Register("NumInputPortNames",&m_NumInputPortNames,ChannelHandler::OUTPUT);
444 m_AudioCH->Register("NumOutputPortNames",&m_NumOutputPortNames,ChannelHandler::OUTPUT);
445 m_AudioCH->RegisterData("InputPortNames",ChannelHandler::OUTPUT,&m_InputPortNames,sizeof(m_InputPortNames));
446 m_AudioCH->RegisterData("OutputPortNames",ChannelHandler::OUTPUT,&m_OutputPortNames,sizeof(m_OutputPortNames));
447 m_AudioCH->Register("UpdateNames",&m_UpdateNames,ChannelHandler::OUTPUT);
448 m_AudioCH->Register("Connected",&m_Connected,ChannelHandler::OUTPUT);
449 }
450
~JackPlugin()451 JackPlugin::~JackPlugin()
452 {
453 if (m_JackClient)
454 {
455 m_JackClient->Detach();
456 delete m_JackClient;
457 m_JackClient=NULL;
458 }
459 }
460
Kill()461 bool JackPlugin::Kill()
462 {
463 m_IsDead=true;
464
465 UpdatePluginInfoWithHost();
466 RemoveAllInputs ();
467 RemoveAllOutputs ();
468 UpdatePluginInfoWithHost();
469
470 m_JackClient->Detach();
471 delete m_JackClient;
472 m_JackClient=NULL;
473 return true;
474 }
475
Initialise(const HostInfo * Host)476 PluginInfo &JackPlugin::Initialise(const HostInfo *Host)
477 {
478 PluginInfo& Info= SpiralPlugin::Initialise(Host);
479 host=Host;
480
481 m_JackClient->SetCallback(cb_Update,m_Parent);
482
483 return Info;
484 }
485
CreateGUI()486 SpiralGUIType *JackPlugin::CreateGUI()
487 {
488 return new JackPluginGUI(m_PluginInfo.Width,
489 m_PluginInfo.Height,
490 this,m_AudioCH,m_HostInfo);
491 }
492
SetNumberPorts(int nInputs,int nOutputs)493 void JackPlugin::SetNumberPorts (int nInputs, int nOutputs) {
494 UpdatePluginInfoWithHost();
495 RemoveAllInputs ();
496 RemoveAllOutputs ();
497 m_PluginInfo.NumInputs = 0;
498 m_PluginInfo.NumOutputs = 0;
499 m_PluginInfo.PortTips.clear ();
500 CreatePorts (nInputs, nOutputs, true);
501 UpdatePluginInfoWithHost ();
502 }
503
CreatePorts(int nInputs,int nOutputs,bool AddPorts)504 void JackPlugin::CreatePorts (int nInputs, int nOutputs, bool AddPorts) {
505 m_PluginInfo.PortTips.clear();
506
507 m_PluginInfo.NumInputs = nInputs;
508 m_JackClient->SetJackInputCount(nInputs);
509
510 for (int n=0; n<nInputs; n++)
511 {
512 char Temp[256];
513 sprintf(Temp,"SSM Input %d",n);
514 m_PluginInfo.PortTips.push_back(Temp);
515 }
516
517 m_PluginInfo.NumOutputs = nOutputs;
518 m_JackClient->SetJackOutputCount(nOutputs);
519
520 for (int n=0; n<nOutputs; n++)
521 {
522 char Temp[256];
523 sprintf(Temp,"SSM Output %d",n);
524 m_PluginInfo.PortTips.push_back(Temp);
525 }
526
527 if (AddPorts) {
528 for (int n=0; n<nInputs; n++) AddInput();
529 for (int n=0; n<nOutputs; n++) AddOutput();
530 }
531
532 }
533
Execute()534 void JackPlugin::Execute()
535 {
536 }
537
ExecuteCommands()538 void JackPlugin::ExecuteCommands()
539 {
540 if (m_IsDead) return;
541
542 bool commandwaiting = m_AudioCH->IsCommandWaiting();
543 int command = (commandwaiting)?(int)m_AudioCH->GetCommand():0;
544
545 if (commandwaiting)
546 {
547 switch (command) {
548 case SET_PORT_COUNT :
549 SetNumberPorts (m_GUIArgs.NumInputs, m_GUIArgs.NumOutputs);
550 }
551 }
552
553
554 // we want to process this whether we are connected to stuff or not
555 JackClient* pJack=m_JackClient;
556
557 // connect the buffers up if we are plugged into something
558 for (int n=0; n<pJack->GetJackOutputCount(); n++)
559 {
560 if (InputExists(n))
561 {
562 pJack->SetOutputBuf(n,(float*)GetInput(n)->GetBuffer());
563 }
564 else
565 {
566 pJack->SetOutputBuf(n,NULL);
567 }
568 }
569
570 for (int n=0; n<pJack->GetJackInputCount(); n++)
571 {
572 if (OutputExists(n))
573 {
574 pJack->SetInputBuf(n,(float*)GetOutputBuf(n)->GetBuffer());
575 }
576 else
577 {
578 pJack->SetInputBuf(n,NULL);
579 }
580 }
581
582 if (commandwaiting)
583 {
584 switch (command)
585 {
586 case UPDATE_NAMES :
587 {
588 int c=0;
589
590 std::vector<string> InputNames,OutputNames;
591 GetPortNames(InputNames,OutputNames);
592 for (vector<string>::iterator i=InputNames.begin();
593 i!=InputNames.end(); ++i)
594 {
595 strcpy(m_InputPortNames[c],i->c_str());
596 c++;
597 }
598
599 c=0;
600
601 for (std::vector<string>::iterator i=OutputNames.begin();
602 i!=OutputNames.end(); ++i)
603 {
604 strcpy(m_OutputPortNames[c],i->c_str());
605 c++;
606 }
607
608 m_NumInputPortNames=InputNames.size();
609 m_NumOutputPortNames=OutputNames.size();
610 }
611 break;
612
613 case CHECK_PORT_CHANGES :
614 if ((m_JackClient->IsAttached()) && (!m_JackClient->CheckingPortChanges)) {
615 m_JackClient->CheckingPortChanges = true;
616
617 for (int n=0; n<m_PluginInfo.NumInputs; n++) {
618 if (jack_port_connected(m_JackClient->m_OutputPortMap[n]->Port)!=m_JackClient->m_OutputPortMap[n]->Connected)
619 m_JackClient->m_OutputPortsChanged.push_back(m_JackClient->m_OutputPortMap[n]);
620
621 if (jack_port_connected(m_JackClient->m_InputPortMap[n]->Port)!=m_JackClient->m_InputPortMap[n]->Connected)
622 m_JackClient->m_InputPortsChanged.push_back(m_JackClient->m_InputPortMap[n]);
623 }
624
625 m_JackClient->CheckingPortChanges = false;
626 }
627
628 break;
629 default : break;
630 }
631 }
632 m_Connected=m_JackClient->IsAttached();
633 }
634
StreamOut(ostream & s)635 void JackPlugin::StreamOut (ostream &s)
636 {
637 s << m_Version << " " << m_GUIArgs.NumInputs << " " << m_GUIArgs.NumOutputs << " ";
638 }
639
StreamIn(istream & s)640 void JackPlugin::StreamIn (istream &s)
641 {
642 char Test;
643 int Version, NumInputs, NumOutputs;
644
645 s.seekg (2, ios::cur ); //skip to next line
646 Test = s.peek(); //peek first char
647 s.seekg (-2, ios::cur ); //jump back to prior line
648
649 if ( (Test >= '0') && (Test <= '9') )
650 {
651 s >> Version;
652 }
653 else
654 {
655 //No Version, so use Version 1
656 Version = 1;
657 }
658
659 switch (Version)
660 {
661 case 2:
662 {
663 s >> NumInputs >> NumOutputs;
664 m_GUIArgs.NumOutputs = min(max(NumOutputs, MIN_PORTS), MAX_PORTS);
665 m_GUIArgs.NumInputs = min(max(NumInputs, MIN_PORTS), MAX_PORTS);
666
667 SetNumberPorts (m_GUIArgs.NumInputs, m_GUIArgs.NumOutputs);
668 }
669 break;
670
671 case 1:
672 {
673 //use original fixed defaults
674 m_GUIArgs.NumInputs = 16;
675 m_GUIArgs.NumOutputs = 16;
676
677 SetNumberPorts (m_GUIArgs.NumInputs, m_GUIArgs.NumOutputs);
678 }
679 break;
680 }
681 }
682