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