new audio engine backend for native CoreAudio audio I/O, and PortMIDI for MIDI.
[ardour.git] / libs / backends / wavesaudio / waves_audiobackend.port_engine.cc
1 /*\r
2     Copyright (C) 2014 Waves Audio Ltd.\r
3 \r
4     This program is free software; you can redistribute it and/or modify\r
5     it under the terms of the GNU General Public License as published by\r
6     the Free Software Foundation; either version 2 of the License, or\r
7     (at your option) any later version.\r
8 \r
9     This program is distributed in the hope that it will be useful,\r
10     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12     GNU General Public License for more details.\r
13 \r
14     You should have received a copy of the GNU General Public License\r
15     along with this program; if not, write to the Free Software\r
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
17 \r
18 */\r
19 \r
20 #include "waves_audiobackend.h"\r
21 #include "waves_audioport.h"\r
22 #include "waves_midiport.h"\r
23 #include "waves_midi_event.h"\r
24 \r
25 using namespace ARDOUR;\r
26 \r
27 uint32_t\r
28 WavesAudioBackend::port_name_size () const\r
29 {\r
30     return 256+64;\r
31 }\r
32 \r
33 int\r
34 WavesAudioBackend::set_port_name (PortHandle port_handle, const std::string& port_name)\r
35 {\r
36     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::set_port_name (): [" << std::hex << port_handle << std::dec << "], [" << port_name << "]" << std::endl;\r
37     \r
38     if (!_registered (port_handle)) {\r
39         std::cerr << "WavesAudioBackend::set_port_name (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;\r
40         return -1;\r
41     }\r
42 \r
43     return ((WavesAudioPort*)port_handle)->set_name (__instantiated_name + ":" + port_name);\r
44 }\r
45 \r
46 \r
47 std::string\r
48 WavesAudioBackend::get_port_name (PortHandle port_handle) const\r
49 {\r
50     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::get_port_name (): [" << std::hex << port_handle << std::dec << "]" << std::endl;\r
51     if (!_registered (port_handle)) {\r
52         std::cerr << "WavesAudioBackend::get_port_name (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;\r
53         return std::string ();\r
54     }\r
55     // COMMENTED DBG LOGS */ else std::cout  << "\t[" << ((WavesAudioPort*)port_handle)->name () << "]" << std::endl;\r
56 \r
57     return ((WavesAudioPort*)port_handle)->name ();\r
58 }\r
59 \r
60 \r
61 PortEngine::PortHandle\r
62 WavesAudioBackend::get_port_by_name (const std::string& port_name) const\r
63 {\r
64     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::get_port_by_name (): [" << port_name << "]" << std::endl;\r
65 \r
66     PortHandle port_handle = (PortHandle)_find_port (port_name);\r
67     if (!port_handle) {\r
68         std::cerr << "WavesAudioBackend::get_port_by_name (): Failed to find port [" << port_name << "]!" << std::endl;\r
69     }\r
70 \r
71     return port_handle;\r
72 }\r
73 \r
74 \r
75 WavesDataPort* \r
76 WavesAudioBackend::_find_port (const std::string& port_name) const\r
77 {\r
78     for (std::vector<WavesDataPort*>::const_iterator it = _ports.begin (); it != _ports.end (); ++it) {\r
79         if ((*it)->name () == port_name) {\r
80             return *it;\r
81         }\r
82     }\r
83 \r
84     return NULL;\r
85 }\r
86 \r
87 \r
88 int\r
89 WavesAudioBackend::get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>& port_names) const\r
90 {\r
91   \r
92     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::get_ports (): \n\tPattern: [" << port_name_pattern << "]\n\tType: " << type << "\n\tFlags: " << flags << endl;\r
93     \r
94     unsigned found_ports =0;\r
95     \r
96     for (size_t i = 0; i < _ports.size (); ++i) {\r
97         WavesDataPort* port = _ports[i];\r
98         \r
99         if ((port->type () == type) && (port->flags () & flags)) {\r
100             port_names.push_back (port->name ());\r
101             found_ports++;\r
102         }\r
103     }\r
104     return found_ports;\r
105 }\r
106 \r
107 \r
108 DataType\r
109 WavesAudioBackend::port_data_type (PortHandle port_handle) const\r
110 {\r
111     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::port_data_type" << std::endl;\r
112 \r
113     if (!_registered (port_handle)) {\r
114         std::cerr << "WavesAudioBackend::port_data_type (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;\r
115         return DataType::NIL;\r
116     }\r
117     \r
118     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::port_data_type: " << endl;\r
119     \r
120     return ((WavesAudioPort*)port_handle)->type ();\r
121 }\r
122 \r
123 \r
124 PortEngine::PortHandle\r
125 WavesAudioBackend::register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags)\r
126 {\r
127     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::register_port (): " << type.to_string () << " [" << shortname << "]" << std::endl;\r
128 \r
129     if (shortname.size () == 0) {\r
130         std::cerr << "WavesAudioBackend::register_port (): Invalid (empty) port name!" << std::endl;\r
131         return NULL;\r
132     }\r
133 \r
134     if (flags & IsPhysical) {\r
135         std::cerr << "WavesAudioBackend::register_port (): Unexpected attribute for port [" << shortname << "]! The port must not be physical!";\r
136         return NULL;\r
137     }\r
138 \r
139     return (PortEngine::PortHandle)_register_port (__instantiated_name + ":" + shortname, type, flags);\r
140 }\r
141 \r
142 \r
143 WavesDataPort*\r
144 WavesAudioBackend::_register_port (const std::string& port_name, ARDOUR::DataType type, ARDOUR::PortFlags flags)\r
145 {\r
146     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::_register_port (): [" << port_name << "]" << std::endl;\r
147 \r
148     if (_find_port (port_name) != NULL) {\r
149         std::cerr << "WavesAudioBackend::register_port () : Port [" << port_name << "] is already registered!" << std::endl;\r
150         return NULL;\r
151     }\r
152 \r
153     WavesDataPort* port = NULL;\r
154     switch (type) {\r
155         case ARDOUR::DataType::AUDIO: {\r
156             WavesAudioPort* audio_port = new WavesAudioPort (port_name, flags);\r
157             if (flags & IsPhysical)\r
158             {\r
159                 if (flags & IsOutput)\r
160                 {\r
161                     _physical_audio_inputs.push_back (audio_port);\r
162                     // COMMENTED DBG LOGS */ std::cout  << "\t\t" << port_name << " added to physical AUDIO Inputs !" << std::endl;\r
163                 }\r
164                 else if (flags & IsInput)\r
165                 {\r
166                     _physical_audio_outputs.push_back (audio_port);\r
167                     // COMMENTED DBG LOGS */ std::cout  << "\t\t" << port_name << " added to physical AUDIO Outputs !" << std::endl;\r
168                 }\r
169             }\r
170             port = audio_port;\r
171         } break;\r
172         case ARDOUR::DataType::MIDI: {\r
173             WavesMidiPort* midi_port = new WavesMidiPort (port_name, flags);\r
174             if (flags & IsPhysical)\r
175             {\r
176                 if (flags & IsOutput)\r
177                 {\r
178                     _physical_midi_inputs.push_back (midi_port);\r
179                     // COMMENTED DBG LOGS */ std::cout  << "\t\t" << port_name << " added to physical MIDI Inputs !" << std::endl;\r
180                 }\r
181                 else if (flags & IsInput)\r
182                 {\r
183                     _physical_midi_outputs.push_back (midi_port);\r
184                     // COMMENTED DBG LOGS */ std::cout  << "\t\t" << port_name << " added to physical MIDI Outputs !" << std::endl;\r
185                 }\r
186             }\r
187             port = midi_port;\r
188         } break;\r
189         default:\r
190             std::cerr << "WavesAudioBackend::register_port () : Invalid data type (" << (uint32_t)type << ") applied to port [" << port_name << "]!" << std::endl;\r
191         return NULL;\r
192     }\r
193     \r
194     _ports.push_back (port);\r
195 \r
196     return port;\r
197 }\r
198 \r
199 \r
200 void\r
201 WavesAudioBackend::unregister_port (PortHandle port_handle)\r
202 {\r
203     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::unregister_port ():" << std::hex << port_handle << std::dec << std::endl;\r
204 \r
205     // so far we suppose all disconnections will be done prior to unregistering.\r
206     WavesDataPort* port = (WavesDataPort*)port_handle;\r
207     std::vector<WavesDataPort*>::iterator port_iterator = std::find (_ports.begin (), _ports.end (), (WavesDataPort*)port_handle);\r
208     if (port_iterator == _ports.end ()) {\r
209         std::cerr << "WavesAudioBackend::unregister_port (): Failed to find port [" << std::hex << port_handle << std::dec << "]!"  << std::endl;\r
210         return;\r
211     }\r
212     // COMMENTED DBG LOGS */ std::cout  << "\t[" << ((WavesDataPort*)port_handle)->name () << "]" << std::endl;\r
213 \r
214     _ports.erase (port_iterator);\r
215 \r
216     if (port->is_physical ()) {\r
217         if (port->is_output ()) {\r
218             switch (port->type ()) {\r
219                 case ARDOUR::DataType::AUDIO: {\r
220                     std::vector<WavesAudioPort*>::iterator audio_port_iterator = std::find (_physical_audio_inputs.begin (), _physical_audio_inputs.end (), port);\r
221                     if (audio_port_iterator == _physical_audio_inputs.end ())    {\r
222                         std::cerr << "WavesAudioBackend::unregister_port (): Failed to find port [" << port->name () << "] in the list of registered physical audio inputs!" << std::endl;\r
223                         return;\r
224                     }\r
225                     _physical_audio_inputs.erase (audio_port_iterator);\r
226                 }\r
227                 break;\r
228                 case ARDOUR::DataType::MIDI: {\r
229                     std::vector<WavesMidiPort*>::iterator midi_port_iterator = std::find (_physical_midi_inputs.begin (), _physical_midi_inputs.end (), port);\r
230                     if (midi_port_iterator == _physical_midi_inputs.end ()) {\r
231                         std::cerr << "WavesAudioBackend::unregister_port (): Failed to find port [" << port->name () << "] in the list of registered physical midi inputs!" << std::endl;\r
232                         return;\r
233                     }\r
234                     _physical_midi_inputs.erase (midi_port_iterator);\r
235                 }\r
236                 break;\r
237                 default:\r
238                     std::cerr << "WavesAudioBackend::unregister_port (): Invalid type (" << port->type () << " applied to [" << port->name () << "]!" << std::endl;\r
239                 break;\r
240             }\r
241         }\r
242         else if (port->flags () & IsInput) {\r
243             switch (port->type ()) {\r
244                 case ARDOUR::DataType::AUDIO: {\r
245                     std::vector<WavesAudioPort*>::iterator audio_port_iterator = std::find (_physical_audio_outputs.begin (), _physical_audio_outputs.end (), port);\r
246                     if (audio_port_iterator == _physical_audio_outputs.end ())\r
247                     {\r
248                         std::cerr << "WavesAudioBackend::unregister_port: Failed to find port [" << port->name () << std::dec << "] in the list of registered physical audio outputs!\n";\r
249                         return;\r
250                     }\r
251                     _physical_audio_outputs.erase (audio_port_iterator);\r
252                 }\r
253                 break;\r
254                 case ARDOUR::DataType::MIDI: {\r
255 \r
256                     std::vector<WavesMidiPort*>::iterator midi_port_iterator = std::find (_physical_midi_outputs.begin (), _physical_midi_outputs.end (), port);\r
257                     if (midi_port_iterator == _physical_midi_outputs.end ())\r
258                     {\r
259                         std::cerr << "WavesAudioBackend::unregister_port: Failed to find port [" << port->name () << std::dec << "] in the list of registered physical midi outputs!\n";\r
260                         return;\r
261                     }\r
262                     _physical_midi_outputs.erase (midi_port_iterator);\r
263                 }\r
264                 break;\r
265                 default:\r
266                     std::cerr << "WavesAudioBackend::unregister_port (): Invalid type (" << port->type () << " applied to [" << port->name () << "]!" << std::endl;\r
267                 break;\r
268             }\r
269         }\r
270     }\r
271 \r
272     delete port;\r
273 }\r
274 \r
275 \r
276 int\r
277 WavesAudioBackend::connect (const std::string& src_port_name, const std::string& dst_port_name)\r
278 {\r
279     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::connect (" << src_port_name << ", " << dst_port_name << "):" << std::endl;\r
280 \r
281     WavesDataPort* src_port = _find_port (src_port_name);\r
282     if (src_port == NULL) {\r
283         std::cerr << "WavesAudioBackend::connect: Failed to find source port " << src_port_name << " !" << std::endl;\r
284         return -1;\r
285     }\r
286     \r
287     WavesDataPort* dst_port = _find_port (dst_port_name);\r
288     if (dst_port == NULL) {\r
289         std::cerr << "WavesAudioBackend::connect: Failed to find destination port " << dst_port_name << " !" << std::endl;\r
290         return -1;\r
291     }\r
292 \r
293     // COMMENTED DBG LOGS */ std::cout  << "\t\t (" << src_port << ", " << dst_port << "):" << std::endl;\r
294     return src_port->connect (dst_port);\r
295 }\r
296 \r
297 \r
298 int\r
299 WavesAudioBackend::connect (PortHandle src_port_handle, const std::string& dst_port_name)\r
300 {\r
301     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::connect ():" << std::endl;\r
302     if (!_registered (src_port_handle)) {\r
303         std::cerr << "WavesAudioBackend::connect: Failed to find source port [" << std::hex << src_port_handle << std::dec << "]!" << std::endl;\r
304         return -1;\r
305     }\r
306 \r
307     // COMMENTED DBG LOGS */ std::cout  << "\t[" << std::hex << src_port_handle << std::dec << "]" << std::endl;\r
308     // COMMENTED DBG LOGS */ std::cout  << "\t[" << dst_port_name << "]" << std::endl;\r
309 \r
310     WavesDataPort* dst_port = _find_port (dst_port_name);\r
311     if (dst_port == NULL) {\r
312         std::cerr << "WavesAudioBackend::connect (): Failed to find destination port [" << dst_port_name << "]!" << std::endl;\r
313         return -1;\r
314     }\r
315 \r
316     return ((WavesDataPort*)src_port_handle)->connect (dst_port);\r
317 }\r
318 \r
319 \r
320 int\r
321 WavesAudioBackend::disconnect (PortHandle src_port_handle, const std::string& dst_port_name)\r
322 {\r
323     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::disconnect (" << src_port_handle << ", " << dst_port_name << "):" << std::endl;\r
324     if (!_registered (src_port_handle)) {\r
325         std::cerr << "WavesAudioBackend::disconnect (): Failed to find source port [" << std::hex << src_port_handle << std::dec << "]!" << std::endl;\r
326         return -1;\r
327     }\r
328     \r
329     // COMMENTED DBG LOGS */ std::cout  << "\t[" << std::hex << src_port_handle << std::dec << "]" << std::endl;\r
330     // COMMENTED DBG LOGS */ std::cout  << "\t[" << dst_port_name << "]" << std::endl;\r
331 \r
332     WavesDataPort* dst_port = _find_port (dst_port_name);\r
333     if (dst_port == NULL) {\r
334         std::cerr << "WavesAudioBackend::disconnect (): Failed to find destination port [" << dst_port_name << "]!" << std::endl;\r
335         return -1;\r
336     }\r
337 \r
338     return ((WavesDataPort*)src_port_handle)->disconnect (dst_port);\r
339 }\r
340 \r
341 \r
342 int\r
343 WavesAudioBackend::disconnect_all (PortHandle port_handle)\r
344 {\r
345     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::disconnect_all ():" << std::endl;\r
346     if (!_registered (port_handle)) {\r
347         std::cerr << "WavesAudioBackend::disconnect_all : Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;\r
348         return -1;\r
349     }\r
350 \r
351  ((WavesDataPort*)port_handle)->disconnect_all ();\r
352 \r
353     return 0;\r
354 }\r
355 \r
356 \r
357 int\r
358 WavesAudioBackend::disconnect (const std::string& src_port_name, const std::string& dst_port_name)\r
359 {\r
360     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::disconnect (" << src_port_name << ", " << dst_port_name << "):" << std::endl;\r
361 \r
362     WavesDataPort* src_port = _find_port (src_port_name);\r
363     if (src_port == NULL) {\r
364         std::cerr << "WavesAudioBackend::disconnect : Failed to find source port!\n";\r
365         return -1;\r
366     }\r
367     \r
368     WavesDataPort* dst_port = _find_port (dst_port_name);\r
369     if (dst_port == NULL) {\r
370         std::cerr << "WavesAudioBackend::disconnect : Failed to find destination port!\n";\r
371         return -1;\r
372     }\r
373 \r
374     return dst_port->disconnect (src_port);\r
375 }\r
376 \r
377 \r
378 bool\r
379 WavesAudioBackend::connected (PortHandle port_handle, bool process_callback_safe)\r
380 {\r
381     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::connected ():" << std::endl;\r
382     if (!_registered (port_handle)) {\r
383         std::cerr << "WavesAudioBackend::connected (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;\r
384         return false;\r
385     }\r
386     \r
387     return ((WavesDataPort*)port_handle)->is_connected ();\r
388 }\r
389 \r
390 \r
391 bool\r
392 WavesAudioBackend::connected_to (PortHandle src_port_handle, const std::string& dst_port_name, bool process_callback_safe)\r
393 {\r
394     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::connected_to (" << src_port_handle << ", " << dst_port_name << ")" << std::endl;\r
395 \r
396     if (!_registered (src_port_handle)) {\r
397         std::cerr << "WavesAudioBackend::connected_to : Failed to find source port!" << std::endl;\r
398         return false;\r
399     }\r
400 \r
401     WavesDataPort* dst_port = _find_port (dst_port_name);\r
402     if (dst_port == NULL) {\r
403         std::cerr << "WavesAudioBackend::connected_to : Failed to find destination port!" << std::endl;\r
404         return -1;\r
405     }\r
406     // COMMENTED DBG LOGS */ std::cout  << "\t return " << ((((WavesDataPort*)src_port_handle)->is_connected (dst_port)) ? "YES":"NO") << ", " << dst_port_name << ")" << std::endl;\r
407     return ((WavesDataPort*)src_port_handle)->is_connected (dst_port);\r
408 }\r
409 \r
410 \r
411 bool\r
412 WavesAudioBackend::physically_connected (PortHandle port_handle, bool process_callback_safe)\r
413 {\r
414     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::physically_connected ():" << std::endl;\r
415 \r
416     if (!_registered (port_handle)) {\r
417         std::cerr << "WavesAudioBackend::physically_connected (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;\r
418         return false;\r
419     }\r
420 \r
421     return ((WavesDataPort*)port_handle)->is_physically_connected ();\r
422 }\r
423 \r
424 \r
425 int\r
426 WavesAudioBackend::get_connections (PortHandle port_handle, std::vector<std::string>& names, bool process_callback_safe)\r
427 {\r
428     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::get_connections ()" << std::endl;\r
429     \r
430     if (!_registered (port_handle)) {\r
431         std::cerr << "WavesAudioBackend::get_connections (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;\r
432         return -1;\r
433     }\r
434 \r
435     if (names.size ()) {\r
436         std::cerr << "WavesAudioBackend::get_connections () : Parameter 'names' is not empty!\n";\r
437         return -1;\r
438     }\r
439  \r
440     const std::vector<WavesDataPort*>& connected_ports = ((WavesDataPort*)port_handle)->get_connections ();\r
441 \r
442     for (std::vector<WavesDataPort*>::const_iterator it = connected_ports.begin (); it != connected_ports.end (); ++it) {\r
443         names.push_back ((*it)->name ());\r
444     }\r
445 \r
446     return (int)names.size ();\r
447 }\r
448 \r
449 \r
450 int\r
451 WavesAudioBackend::request_input_monitoring (PortHandle, bool)\r
452 {\r
453     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::request_input_monitoring: " << std::endl;\r
454     return 0;\r
455 }\r
456 \r
457 \r
458 int\r
459 WavesAudioBackend::ensure_input_monitoring (PortHandle, bool)\r
460 {\r
461     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::ensure_input_monitoring: " << std::endl;\r
462     return 0;\r
463 }\r
464 \r
465 \r
466 bool\r
467 WavesAudioBackend::monitoring_input (PortHandle)\r
468 {\r
469     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::monitoring_input: " << std::endl;\r
470     return false;\r
471 }\r
472 \r
473 \r
474 bool\r
475 WavesAudioBackend::port_is_physical (PortHandle port_handle) const\r
476 {\r
477     \r
478     if (!_registered (port_handle)) {\r
479         std::cerr << "WavesAudioBackend::port_is_physical (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;\r
480         return -1;\r
481     }\r
482     \r
483     return (((WavesAudioPort*)port_handle)->flags () & IsPhysical) != 0;\r
484 }\r
485 \r
486 \r
487 void\r
488 WavesAudioBackend::get_physical_outputs (DataType type, std::vector<std::string>& names)\r
489 {\r
490     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::get_physical_outputs ():" << std::endl << "\tdatatype = " << type << std::endl;\r
491 \r
492     switch (type) {\r
493         case ARDOUR::DataType::AUDIO: {\r
494             for (std::vector<WavesAudioPort*>::iterator it = _physical_audio_outputs.begin (); it != _physical_audio_outputs.end (); ++it) {\r
495                 // COMMENTED DBG LOGS */ std::cout  << "\t" << (*it)->name () << std::endl;\r
496                 names.push_back ((*it)->name ());\r
497             }\r
498         } break;\r
499         case ARDOUR::DataType::MIDI: {\r
500             for (std::vector<WavesMidiPort*>::iterator it = _physical_midi_outputs.begin (); it != _physical_midi_outputs.end (); ++it) {\r
501                 // COMMENTED DBG LOGS */ std::cout  << "\t" << (*it)->name () << std::endl;\r
502                 names.push_back ((*it)->name ());\r
503             }\r
504         } break;\r
505         default:\r
506             break;\r
507     }\r
508 }\r
509 \r
510 \r
511 void\r
512 WavesAudioBackend::get_physical_inputs (DataType type, std::vector<std::string>& names)\r
513 {\r
514     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::get_physical_inputs ():" << std::endl << "\tdatatype = " << type << std::endl;\r
515     switch (type) {\r
516         case ARDOUR::DataType::AUDIO: {\r
517             for (std::vector<WavesAudioPort*>::iterator it = _physical_audio_inputs.begin (); it != _physical_audio_inputs.end (); ++it) {\r
518                 // COMMENTED DBG LOGS */ std::cout  << "\t" << (*it)->name () << std::endl;\r
519                 names.push_back ((*it)->name ());\r
520             }\r
521         } break;\r
522         case ARDOUR::DataType::MIDI: {\r
523             for (std::vector<WavesMidiPort*>::iterator it = _physical_midi_inputs.begin (); it != _physical_midi_inputs.end (); ++it) {\r
524                 // COMMENTED DBG LOGS */ std::cout  << "\t" << (*it)->name () << std::endl;\r
525                 names.push_back ((*it)->name ());\r
526             }\r
527         } break;\r
528         default:\r
529         break;\r
530     }\r
531 }\r
532 \r
533 \r
534 ChanCount\r
535 WavesAudioBackend::n_physical_outputs () const\r
536 {\r
537     ChanCount chan_count;\r
538     chan_count.set (DataType::AUDIO, _physical_audio_outputs.size ());\r
539     chan_count.set (DataType::MIDI, _physical_midi_outputs.size ());\r
540 \r
541     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::n_physical_outputs ():" << std::endl << "\ttotal = " << chan_count.n_total () << std::endl;\r
542 \r
543     return chan_count;\r
544 }\r
545 \r
546 \r
547 ChanCount\r
548 WavesAudioBackend::n_physical_inputs () const\r
549 {\r
550     ChanCount chan_count;\r
551     chan_count.set (DataType::AUDIO, _physical_audio_inputs.size ());\r
552     chan_count.set (DataType::MIDI, _physical_midi_inputs.size ());\r
553 \r
554     // COMMENTED DBG LOGS */ std::cout  << "WavesAudioBackend::n_physical_outputs ():" << std::endl << "\ttotal = " << chan_count.n_total () << std::endl;\r
555 \r
556     return chan_count;\r
557 }\r
558 \r
559 \r
560 void*\r
561 WavesAudioBackend::get_buffer (PortHandle port_handle, pframes_t nframes)\r
562 {\r
563     // Here we would check if the port is registered. However, we will not do it as\r
564     // it's relatively VERY SLOW operation. So let's count on consistency\r
565     // of the caller as get_buffer normally is called hundreds of "kilotimes" per second.\r
566 \r
567     if (port_handle == NULL) {\r
568         std::cerr << "WavesAudioBackend::get_buffer : Invalid port handler <NULL>!" << std::endl;\r
569         return NULL;\r
570     }  \r
571     \r
572     return ((WavesAudioPort*)port_handle)->get_buffer (nframes);\r
573 }\r
574 \r
575 \r
576 int\r
577 WavesAudioBackend::_register_system_audio_ports ()\r
578 {\r
579     if (!_device) {\r
580         std::cerr << "WavesAudioBackend::_register_system_audio_ports (): No device is set!" << std::endl;\r
581         return -1;\r
582     }\r
583     \r
584     std::vector<std::string> input_channels = _device->InputChannels ();\r
585     _max_input_channels = input_channels.size ();\r
586     \r
587     uint32_t channels = (_input_channels ? _input_channels : input_channels.size ());\r
588     uint32_t port_number = 0;\r
589 \r
590     LatencyRange lr = {0,0};\r
591 \r
592     // Get latency for capture\r
593     lr.min = lr.max = _device->GetLatency (false) + _device->CurrentBufferSize () + _systemic_input_latency;\r
594     for (std::vector<std::string>::iterator it = input_channels.begin (); \r
595          (port_number < channels) && (it != input_channels.end ());\r
596         ++it) {\r
597         std::ostringstream port_name;\r
598         port_name << "capture_" << ++port_number;\r
599 \r
600         WavesDataPort* port = _register_port ("system:" + port_name.str (), DataType::AUDIO , static_cast<PortFlags> (IsOutput | IsPhysical | IsTerminal));\r
601         if (port == NULL) {\r
602             std::cerr << "WavesAudioBackend::_create_system_audio_ports (): Failed registering port [" << port_name << "] for [" << _device->DeviceName () << "]" << std::endl;\r
603             return-1;\r
604         }\r
605         set_latency_range (port, false, lr);\r
606     }\r
607     \r
608     std::vector<std::string> output_channels = _device->OutputChannels ();\r
609     _max_output_channels = output_channels.size ();\r
610     channels = (_output_channels ? _output_channels : _max_output_channels);\r
611     port_number = 0;\r
612     \r
613     // Get latency for playback\r
614     lr.min = lr.max = _device->GetLatency (true) + _device->CurrentBufferSize () + _systemic_output_latency;\r
615 \r
616     for (std::vector<std::string>::iterator it = output_channels.begin ();\r
617          (port_number < channels) && (it != output_channels.end ());\r
618         ++it) {\r
619         std::ostringstream port_name;\r
620         port_name << "playback_" << ++port_number;\r
621         WavesDataPort* port = _register_port ("system:" + port_name.str (), DataType::AUDIO , static_cast<PortFlags> (IsInput| IsPhysical | IsTerminal));\r
622         if (port == NULL) {\r
623             std::cerr << "WavesAudioBackend::_create_system_audio_ports (): Failed registering port ]" << port_name << "] for [" << _device->DeviceName () << "]" << std::endl;\r
624             return-1;\r
625         }\r
626         set_latency_range (port, true, lr);\r
627     }\r
628     \r
629     return 0;\r
630 }\r
631 \r
632 \r
633 void\r
634 WavesAudioBackend::_unregister_system_audio_ports ()\r
635 {\r
636     std::vector<WavesAudioPort*> physical_audio_ports = _physical_audio_inputs;\r
637     physical_audio_ports.insert (physical_audio_ports.begin (), _physical_audio_outputs.begin (), _physical_audio_outputs.end ());\r
638         \r
639     for (std::vector<WavesAudioPort*>::const_iterator it = physical_audio_ports.begin (); it != physical_audio_ports.end (); ++it) {\r
640         std::vector<WavesDataPort*>::iterator port_iterator = std::find (_ports.begin (), _ports.end (), *it);\r
641         if (port_iterator == _ports.end ()) {\r
642             std::cerr << "WavesAudioBackend::_unregister_system_audio_ports (): Failed to find port [" << (*it)->name () << "]!"  << std::endl;\r
643         }\r
644         else {\r
645             _ports.erase (port_iterator);\r
646         }\r
647         delete *it;\r
648     }\r
649 \r
650     _physical_audio_inputs.clear ();\r
651     _physical_audio_outputs.clear ();\r
652 }\r
653 \r
654 \r