NOOP, remove trailing tabs/whitespace.
[ardour.git] / libs / ardour / port_manager.cc
1 /*
2     Copyright (C) 2013 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "pbd/convert.h"
21 #include "pbd/error.h"
22
23 #include "ardour/async_midi_port.h"
24 #include "ardour/audio_backend.h"
25 #include "ardour/audio_port.h"
26 #include "ardour/debug.h"
27 #include "ardour/midi_port.h"
28 #include "ardour/midiport_manager.h"
29 #include "ardour/port_manager.h"
30 #include "ardour/profile.h"
31
32 #include "i18n.h"
33
34 using namespace ARDOUR;
35 using namespace PBD;
36 using std::string;
37 using std::vector;
38
39 PortManager::PortManager ()
40         : ports (new Ports)
41         , _port_remove_in_progress (false)
42 {
43 }
44
45 void
46 PortManager::remove_all_ports ()
47 {
48         /* make sure that JACK callbacks that will be invoked as we cleanup
49          * ports know that they have nothing to do.
50          */
51
52         _port_remove_in_progress = true;
53
54         /* process lock MUST be held by caller
55         */
56
57         {
58                 RCUWriter<Ports> writer (ports);
59                 boost::shared_ptr<Ports> ps = writer.get_copy ();
60                 ps->clear ();
61         }
62
63         /* clear dead wood list in RCU */
64
65         ports.flush ();
66
67         _port_remove_in_progress = false;
68 }
69
70
71 string
72 PortManager::make_port_name_relative (const string& portname) const
73 {
74         if (!_backend) {
75                 return portname;
76         }
77
78         string::size_type len;
79         string::size_type n;
80         string self = _backend->my_name();
81
82         len = portname.length();
83
84         for (n = 0; n < len; ++n) {
85                 if (portname[n] == ':') {
86                         break;
87                 }
88         }
89
90         if ((n != len) && (portname.substr (0, n) == self)) {
91                 return portname.substr (n+1);
92         }
93
94         return portname;
95 }
96
97 string
98 PortManager::make_port_name_non_relative (const string& portname) const
99 {
100         string str;
101
102         if (portname.find_first_of (':') != string::npos) {
103                 return portname;
104         }
105
106         str  = _backend->my_name();
107         str += ':';
108         str += portname;
109
110         return str;
111 }
112
113 std::string
114 PortManager::get_pretty_name_by_name(const std::string& portname) const
115 {
116         PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
117         if (ph) {
118                 std::string value;
119                 std::string type;
120                 if (0 == _backend->get_port_property (ph,
121                                         "http://jackaudio.org/metadata/pretty-name",
122                                         value, type))
123                 {
124                         return value;
125                 }
126         }
127         return "";
128 }
129
130 bool
131 PortManager::port_is_mine (const string& portname) const
132 {
133         if (!_backend) {
134                 return true;
135         }
136
137         string self = _backend->my_name();
138
139         if (portname.find_first_of (':') != string::npos) {
140                 if (portname.substr (0, self.length ()) != self) {
141                         return false;
142                 }
143         }
144
145         return true;
146 }
147
148 bool
149 PortManager::port_is_physical (const std::string& portname) const
150 {
151         if (!_backend) {
152                 return false;
153         }
154
155         PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
156         if (!ph) {
157                 return false;
158         }
159
160         return _backend->port_is_physical (ph);
161 }
162
163 void
164 PortManager::get_physical_outputs (DataType type, std::vector<std::string>& s)
165 {
166         if (!_backend) {
167                 return;
168         }
169         _backend->get_physical_outputs (type, s);
170 }
171
172 void
173 PortManager::get_physical_inputs (DataType type, std::vector<std::string>& s)
174 {
175         if (!_backend) {
176                 return;
177         }
178
179         _backend->get_physical_inputs (type, s);
180 }
181
182 ChanCount
183 PortManager::n_physical_outputs () const
184 {
185         if (!_backend) {
186                 return ChanCount::ZERO;
187         }
188
189         return _backend->n_physical_outputs ();
190 }
191
192 ChanCount
193 PortManager::n_physical_inputs () const
194 {
195         if (!_backend) {
196                 return ChanCount::ZERO;
197         }
198         return _backend->n_physical_inputs ();
199 }
200
201 bool
202 PortManager::port_name_prefix_is_unique (const string& first_part_of_port_name) const
203 {
204         if (!_backend) {
205                 return boost::shared_ptr<Port>();
206         }
207
208         boost::shared_ptr<const Ports> pr = ports.reader();
209         const string::size_type len = first_part_of_port_name.length();
210
211         for (Ports::const_iterator x = pr->begin(); x != pr->end(); ++x) {
212
213                 string prefix = x->first.substr (0, len);
214
215                 if (strings_equal_ignore_case (prefix, first_part_of_port_name)) {
216                         return false;
217                 }
218         }
219
220         return true;
221 }
222
223 /** @param name Full or short name of port
224  *  @return Corresponding Port or 0.
225  */
226
227 boost::shared_ptr<Port>
228 PortManager::get_port_by_name (const string& portname)
229 {
230         if (!_backend) {
231                 return boost::shared_ptr<Port>();
232         }
233
234         if (!port_is_mine (portname)) {
235                 /* not an ardour port */
236                 return boost::shared_ptr<Port> ();
237         }
238
239         boost::shared_ptr<Ports> pr = ports.reader();
240         std::string rel = make_port_name_relative (portname);
241         Ports::iterator x = pr->find (rel);
242
243         if (x != pr->end()) {
244                 /* its possible that the port was renamed by some 3rd party and
245                    we don't know about it. check for this (the check is quick
246                    and cheap), and if so, rename the port (which will alter
247                    the port map as a side effect).
248                 */
249                 const std::string check = make_port_name_relative (_backend->get_port_name (x->second->port_handle()));
250                 if (check != rel) {
251                         x->second->set_name (check);
252                 }
253                 return x->second;
254         }
255
256         return boost::shared_ptr<Port> ();
257 }
258
259 void
260 PortManager::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
261 {
262         RCUWriter<Ports> writer (ports);
263         boost::shared_ptr<Ports> p = writer.get_copy();
264         Ports::iterator x = p->find (old_relative_name);
265
266         if (x != p->end()) {
267                 boost::shared_ptr<Port> port = x->second;
268                 p->erase (x);
269                 p->insert (make_pair (new_relative_name, port));
270         }
271 }
272
273 int
274 PortManager::get_ports (DataType type, PortList& pl)
275 {
276         boost::shared_ptr<Ports> plist = ports.reader();
277         for (Ports::iterator p = plist->begin(); p != plist->end(); ++p) {
278                 if (p->second->type() == type) {
279                         pl.push_back (p->second);
280                 }
281         }
282         return pl.size();
283 }
284
285 int
286 PortManager::get_ports (const string& port_name_pattern, DataType type, PortFlags flags, vector<string>& s)
287 {
288         s.clear();
289
290         if (!_backend) {
291                 return 0;
292         }
293
294         return _backend->get_ports (port_name_pattern, type, flags, s);
295 }
296
297 void
298 PortManager::port_registration_failure (const std::string& portname)
299 {
300         if (!_backend) {
301                 return;
302         }
303
304         string full_portname = _backend->my_name();
305         full_portname += ':';
306         full_portname += portname;
307
308
309         PortEngine::PortHandle p = _backend->get_port_by_name (full_portname);
310         string reason;
311
312         if (p) {
313                 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
314         } else {
315                 reason = string_compose (_("No more ports are available. You will need to stop %1 and restart with more ports if you need this many tracks."), PROGRAM_NAME);
316         }
317
318         throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
319 }
320
321 boost::shared_ptr<Port>
322 PortManager::register_port (DataType dtype, const string& portname, bool input, bool async)
323 {
324         boost::shared_ptr<Port> newport;
325
326         try {
327                 if (dtype == DataType::AUDIO) {
328                         DEBUG_TRACE (DEBUG::Ports, string_compose ("registering AUDIO port %1, input %2\n",
329                                                                    portname, input));
330                         newport.reset (new AudioPort (portname, (input ? IsInput : IsOutput)));
331                 } else if (dtype == DataType::MIDI) {
332                         if (async) {
333                                 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering ASYNC MIDI port %1, input %2\n",
334                                                                            portname, input));
335                                 newport.reset (new AsyncMIDIPort (portname, (input ? IsInput : IsOutput)));
336                         } else {
337                                 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering MIDI port %1, input %2\n",
338                                                                            portname, input));
339                                 newport.reset (new MidiPort (portname, (input ? IsInput : IsOutput)));
340                         }
341                 } else {
342                         throw PortRegistrationFailure("unable to create port (unknown type)");
343                 }
344
345                 RCUWriter<Ports> writer (ports);
346                 boost::shared_ptr<Ports> ps = writer.get_copy ();
347                 ps->insert (make_pair (make_port_name_relative (portname), newport));
348
349                 /* writer goes out of scope, forces update */
350
351         }
352
353         catch (PortRegistrationFailure& err) {
354                 throw err;
355         } catch (std::exception& e) {
356                 throw PortRegistrationFailure(string_compose(
357                                 _("unable to create port: %1"), e.what()).c_str());
358         } catch (...) {
359                 throw PortRegistrationFailure("unable to create port (unknown error)");
360         }
361
362         DEBUG_TRACE (DEBUG::Ports, string_compose ("\t%2 port registration success, ports now = %1\n", ports.reader()->size(), this));
363         return newport;
364 }
365
366 boost::shared_ptr<Port>
367 PortManager::register_input_port (DataType type, const string& portname, bool async)
368 {
369         return register_port (type, portname, true, async);
370 }
371
372 boost::shared_ptr<Port>
373 PortManager::register_output_port (DataType type, const string& portname, bool async)
374 {
375         return register_port (type, portname, false, async);
376 }
377
378 int
379 PortManager::unregister_port (boost::shared_ptr<Port> port)
380 {
381         /* caller must hold process lock */
382
383         {
384                 RCUWriter<Ports> writer (ports);
385                 boost::shared_ptr<Ports> ps = writer.get_copy ();
386                 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
387
388                 if (x != ps->end()) {
389                         ps->erase (x);
390                 }
391
392                 /* writer goes out of scope, forces update */
393         }
394
395         ports.flush ();
396
397         return 0;
398 }
399
400 bool
401 PortManager::connected (const string& port_name)
402 {
403         if (!_backend) {
404                 return false;
405         }
406
407         PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
408
409         if (!handle) {
410                 return false;
411         }
412
413         return _backend->connected (handle);
414 }
415
416 int
417 PortManager::connect (const string& source, const string& destination)
418 {
419         int ret;
420
421         string s = make_port_name_non_relative (source);
422         string d = make_port_name_non_relative (destination);
423
424         boost::shared_ptr<Port> src = get_port_by_name (s);
425         boost::shared_ptr<Port> dst = get_port_by_name (d);
426
427         if (src) {
428                 ret = src->connect (d);
429         } else if (dst) {
430                 ret = dst->connect (s);
431         } else {
432                 /* neither port is known to us ...hand-off to the PortEngine
433                  */
434                 if (_backend) {
435                         ret = _backend->connect (s, d);
436                 } else {
437                         ret = -1;
438                 }
439         }
440
441         if (ret > 0) {
442                 /* already exists - no error, no warning */
443         } else if (ret < 0) {
444                 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
445                                         source, s, destination, d)
446                       << endmsg;
447         }
448
449         return ret;
450 }
451
452 int
453 PortManager::disconnect (const string& source, const string& destination)
454 {
455         int ret;
456
457         string s = make_port_name_non_relative (source);
458         string d = make_port_name_non_relative (destination);
459
460         boost::shared_ptr<Port> src = get_port_by_name (s);
461         boost::shared_ptr<Port> dst = get_port_by_name (d);
462
463         if (src) {
464                 ret = src->disconnect (d);
465         } else if (dst) {
466                 ret = dst->disconnect (s);
467         } else {
468                 /* neither port is known to us ...hand-off to the PortEngine
469                  */
470                 if (_backend) {
471                         ret = _backend->disconnect (s, d);
472                 } else {
473                         ret = -1;
474                 }
475         }
476         return ret;
477 }
478
479 int
480 PortManager::disconnect (boost::shared_ptr<Port> port)
481 {
482         return port->disconnect_all ();
483 }
484
485 int
486 PortManager::reestablish_ports ()
487 {
488         Ports::iterator i;
489
490         boost::shared_ptr<Ports> p = ports.reader ();
491
492         DEBUG_TRACE (DEBUG::Ports, string_compose ("reestablish %1 ports\n", p->size()));
493
494         for (i = p->begin(); i != p->end(); ++i) {
495                 if (i->second->reestablish ()) {
496                         error << string_compose (_("Re-establising port %1 failed"), i->second->name()) << endmsg;
497                         std::cerr << string_compose (_("Re-establising port %1 failed"), i->second->name()) << std::endl;
498                         break;
499                 }
500         }
501
502         if (i != p->end()) {
503                 /* failed */
504                 remove_all_ports ();
505                 return -1;
506         }
507
508         return 0;
509 }
510
511 int
512 PortManager::reconnect_ports ()
513 {
514         boost::shared_ptr<Ports> p = ports.reader ();
515
516         if (!Profile->get_trx()) {
517                 /* re-establish connections */
518
519                 DEBUG_TRACE (DEBUG::Ports, string_compose ("reconnect %1 ports\n", p->size()));
520
521                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
522                         i->second->reconnect ();
523                 }
524         }
525
526         return 0;
527 }
528
529 void
530 PortManager::connect_callback (const string& a, const string& b, bool conn)
531 {
532         boost::shared_ptr<Port> port_a;
533         boost::shared_ptr<Port> port_b;
534         Ports::iterator x;
535         boost::shared_ptr<Ports> pr = ports.reader ();
536
537         x = pr->find (make_port_name_relative (a));
538         if (x != pr->end()) {
539                 port_a = x->second;
540         }
541
542         x = pr->find (make_port_name_relative (b));
543         if (x != pr->end()) {
544                 port_b = x->second;
545         }
546
547         PortConnectedOrDisconnected (
548                 port_a, a,
549                 port_b, b,
550                 conn
551                 ); /* EMIT SIGNAL */
552 }
553
554 void
555 PortManager::registration_callback ()
556 {
557         if (!_port_remove_in_progress) {
558                 PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
559         }
560 }
561
562 bool
563 PortManager::can_request_input_monitoring () const
564 {
565         if (!_backend) {
566                 return false;
567         }
568
569         return _backend->can_monitor_input ();
570 }
571
572 void
573 PortManager::request_input_monitoring (const string& name, bool yn) const
574 {
575         if (!_backend) {
576                 return;
577         }
578
579         PortEngine::PortHandle ph = _backend->get_port_by_name (name);
580
581         if (ph) {
582                 _backend->request_input_monitoring (ph, yn);
583         }
584 }
585
586 void
587 PortManager::ensure_input_monitoring (const string& name, bool yn) const
588 {
589         if (!_backend) {
590                 return;
591         }
592
593         PortEngine::PortHandle ph = _backend->get_port_by_name (name);
594
595         if (ph) {
596                 _backend->ensure_input_monitoring (ph, yn);
597         }
598 }
599
600 uint32_t
601 PortManager::port_name_size() const
602 {
603         if (!_backend) {
604                 return 0;
605         }
606
607         return _backend->port_name_size ();
608 }
609
610 string
611 PortManager::my_name() const
612 {
613         if (!_backend) {
614                 return string();
615         }
616
617         return _backend->my_name();
618 }
619
620 int
621 PortManager::graph_order_callback ()
622 {
623         if (!_port_remove_in_progress) {
624                 GraphReordered(); /* EMIT SIGNAL */
625         }
626
627         return 0;
628 }
629
630 void
631 PortManager::cycle_start (pframes_t nframes)
632 {
633         Port::set_global_port_buffer_offset (0);
634         Port::set_cycle_framecnt (nframes);
635
636         _cycle_ports = ports.reader ();
637
638         for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
639                 p->second->cycle_start (nframes);
640         }
641 }
642
643 void
644 PortManager::cycle_end (pframes_t nframes)
645 {
646         for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
647                 p->second->cycle_end (nframes);
648         }
649
650         for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
651                 p->second->flush_buffers (nframes);
652         }
653
654         _cycle_ports.reset ();
655
656         /* we are done */
657 }
658
659 void
660 PortManager::silence (pframes_t nframes)
661 {
662         for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
663                 if (i->second->sends_output()) {
664                         i->second->get_buffer(nframes).silence(nframes);
665                 }
666         }
667 }
668
669 void
670 PortManager::silence_outputs (pframes_t nframes)
671 {
672         std::vector<std::string> port_names;
673         if (get_ports("", DataType::AUDIO, IsOutput, port_names)) {
674                 for (std::vector<std::string>::iterator p = port_names.begin(); p != port_names.end(); ++p) {
675                         if (!port_is_mine(*p)) {
676                                 continue;
677                         }
678                         PortEngine::PortHandle ph = _backend->get_port_by_name (*p);
679                         if (!ph) {
680                                 continue;
681                         }
682                         void *buf = _backend->get_buffer(ph, nframes);
683                         if (!buf) {
684                                 continue;
685                         }
686                         memset (buf, 0, sizeof(float) * nframes);
687                 }
688         }
689
690         if (get_ports("", DataType::MIDI, IsOutput, port_names)) {
691                 for (std::vector<std::string>::iterator p = port_names.begin(); p != port_names.end(); ++p) {
692                         if (!port_is_mine(*p)) {
693                                 continue;
694                         }
695                         PortEngine::PortHandle ph = _backend->get_port_by_name (*p);
696                         if (!ph) {
697                                 continue;
698                         }
699                         void *buf = _backend->get_buffer(ph, nframes);
700                         if (!buf) {
701                                 continue;
702                         }
703                         _backend->midi_clear (buf);
704                 }
705         }
706 }
707
708 void
709 PortManager::check_monitoring ()
710 {
711         for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
712
713                 bool x;
714
715                 if (i->second->last_monitor() != (x = i->second->monitoring_input ())) {
716                         i->second->set_last_monitor (x);
717                         /* XXX I think this is dangerous, due to
718                            a likely mutex in the signal handlers ...
719                         */
720                         i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
721                 }
722         }
723 }
724
725 void
726 PortManager::fade_out (gain_t base_gain, gain_t gain_step, pframes_t nframes)
727 {
728         for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
729
730                 if (i->second->sends_output()) {
731
732                         boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
733                         if (ap) {
734                                 Sample* s = ap->engine_get_whole_audio_buffer ();
735                                 gain_t g = base_gain;
736
737                                 for (pframes_t n = 0; n < nframes; ++n) {
738                                         *s++ *= g;
739                                         g -= gain_step;
740                                 }
741                         }
742                 }
743         }
744 }
745
746 PortEngine&
747 PortManager::port_engine()
748 {
749         assert (_backend);
750         return *_backend;
751 }