new scheme for managing port deletion
[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 #ifdef COMPILER_MSVC
21 #include <io.h> // Microsoft's nearest equivalent to <unistd.h>
22 #include <ardourext/misc.h>
23 #else
24 #include <regex.h>
25 #endif
26
27 #include "pbd/convert.h"
28 #include "pbd/error.h"
29
30 #include "ardour/async_midi_port.h"
31 #include "ardour/audio_backend.h"
32 #include "ardour/audio_port.h"
33 #include "ardour/debug.h"
34 #include "ardour/midi_port.h"
35 #include "ardour/midiport_manager.h"
36 #include "ardour/port_manager.h"
37 #include "ardour/profile.h"
38 #include "ardour/session.h"
39
40 #include "pbd/i18n.h"
41
42 using namespace ARDOUR;
43 using namespace PBD;
44 using std::string;
45 using std::vector;
46
47 PortManager::PortManager ()
48         : ports (new Ports)
49         , _port_remove_in_progress (false)
50         , _port_deletions_pending (8192) /* ick, arbitrary sizing */
51 {
52 }
53
54 void
55 PortManager::clear_pending_port_deletions ()
56 {
57         Port* p;
58
59         while (_port_deletions_pending.read (&p, 1) == 1) {
60                 delete p;
61         }
62 }
63
64 void
65 PortManager::remove_all_ports ()
66 {
67         /* make sure that JACK callbacks that will be invoked as we cleanup
68          * ports know that they have nothing to do.
69          */
70
71         _port_remove_in_progress = true;
72
73         /* process lock MUST be held by caller
74         */
75
76         {
77                 RCUWriter<Ports> writer (ports);
78                 boost::shared_ptr<Ports> ps = writer.get_copy ();
79                 ps->clear ();
80         }
81
82         /* clear dead wood list in RCU */
83
84         ports.flush ();
85
86         /* clear out pending port deletion list. we know this is safe because
87          * the auto connect thread in Session is already dead when this is
88          * done. It doesn't use shared_ptr<Port> anyway.
89          */
90
91         _port_deletions_pending.reset ();
92
93         _port_remove_in_progress = false;
94 }
95
96
97 string
98 PortManager::make_port_name_relative (const string& portname) const
99 {
100         if (!_backend) {
101                 return portname;
102         }
103
104         string::size_type colon = portname.find (':');
105
106         if (colon == string::npos) {
107                 return portname;
108         }
109
110         if (portname.substr (0, colon) == _backend->my_name()) {
111                 return portname.substr (colon+1);
112         }
113
114         return portname;
115 }
116
117 string
118 PortManager::make_port_name_non_relative (const string& portname) const
119 {
120         string str;
121
122         if (portname.find_first_of (':') != string::npos) {
123                 return portname;
124         }
125
126         str  = _backend->my_name();
127         str += ':';
128         str += portname;
129
130         return str;
131 }
132
133 std::string
134 PortManager::get_pretty_name_by_name(const std::string& portname) const
135 {
136         PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
137         if (ph) {
138                 std::string value;
139                 std::string type;
140                 if (0 == _backend->get_port_property (ph,
141                                         "http://jackaudio.org/metadata/pretty-name",
142                                         value, type))
143                 {
144                         return value;
145                 }
146         }
147         return "";
148 }
149
150 bool
151 PortManager::port_is_mine (const string& portname) const
152 {
153         if (!_backend) {
154                 return true;
155         }
156
157         string self = _backend->my_name();
158
159         if (portname.find_first_of (':') != string::npos) {
160                 if (portname.substr (0, self.length ()) != self) {
161                         return false;
162                 }
163         }
164
165         return true;
166 }
167
168 bool
169 PortManager::port_is_physical (const std::string& portname) const
170 {
171         if (!_backend) {
172                 return false;
173         }
174
175         PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
176         if (!ph) {
177                 return false;
178         }
179
180         return _backend->port_is_physical (ph);
181 }
182
183 void
184 PortManager::get_physical_outputs (DataType type, std::vector<std::string>& s)
185 {
186         if (!_backend) {
187                 s.clear ();
188                 return;
189         }
190         _backend->get_physical_outputs (type, s);
191 }
192
193 void
194 PortManager::get_physical_inputs (DataType type, std::vector<std::string>& s)
195 {
196         if (!_backend) {
197                 s.clear ();
198                 return;
199         }
200
201         _backend->get_physical_inputs (type, s);
202 }
203
204 ChanCount
205 PortManager::n_physical_outputs () const
206 {
207         if (!_backend) {
208                 return ChanCount::ZERO;
209         }
210
211         return _backend->n_physical_outputs ();
212 }
213
214 ChanCount
215 PortManager::n_physical_inputs () const
216 {
217         if (!_backend) {
218                 return ChanCount::ZERO;
219         }
220         return _backend->n_physical_inputs ();
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 struct PortDeleter
322 {
323         void operator() (Port* p) {
324                 AudioEngine::instance()->add_pending_port_deletion (p);
325         }
326 };
327
328 boost::shared_ptr<Port>
329 PortManager::register_port (DataType dtype, const string& portname, bool input, bool async, PortFlags flags)
330 {
331         boost::shared_ptr<Port> newport;
332
333         /* limit the possible flags that can be set */
334
335         flags = PortFlags (flags & (Hidden|Shadow|IsTerminal));
336
337         try {
338                 if (dtype == DataType::AUDIO) {
339                         DEBUG_TRACE (DEBUG::Ports, string_compose ("registering AUDIO port %1, input %2\n",
340                                                                    portname, input));
341                         newport.reset (new AudioPort (portname, PortFlags ((input ? IsInput : IsOutput) | flags)),
342                                        PortDeleter());
343                 } else if (dtype == DataType::MIDI) {
344                         if (async) {
345                                 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering ASYNC MIDI port %1, input %2\n",
346                                                                            portname, input));
347                                 newport.reset (new AsyncMIDIPort (portname, PortFlags ((input ? IsInput : IsOutput) | flags)),
348                                                PortDeleter());
349                         } else {
350                                 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering MIDI port %1, input %2\n",
351                                                                            portname, input));
352                                 newport.reset (new MidiPort (portname, PortFlags ((input ? IsInput : IsOutput) | flags)),
353                                                PortDeleter());
354                         }
355                 } else {
356                         throw PortRegistrationFailure("unable to create port (unknown type)");
357                 }
358
359                 RCUWriter<Ports> writer (ports);
360                 boost::shared_ptr<Ports> ps = writer.get_copy ();
361                 ps->insert (make_pair (make_port_name_relative (portname), newport));
362
363                 /* writer goes out of scope, forces update */
364
365         }
366
367         catch (PortRegistrationFailure& err) {
368                 throw err;
369         } catch (std::exception& e) {
370                 throw PortRegistrationFailure(string_compose(
371                                 _("unable to create port: %1"), e.what()).c_str());
372         } catch (...) {
373                 throw PortRegistrationFailure("unable to create port (unknown error)");
374         }
375
376         DEBUG_TRACE (DEBUG::Ports, string_compose ("\t%2 port registration success, ports now = %1\n", ports.reader()->size(), this));
377         return newport;
378 }
379
380 boost::shared_ptr<Port>
381 PortManager::register_input_port (DataType type, const string& portname, bool async, PortFlags extra_flags)
382 {
383         return register_port (type, portname, true, async, extra_flags);
384 }
385
386 boost::shared_ptr<Port>
387 PortManager::register_output_port (DataType type, const string& portname, bool async, PortFlags extra_flags)
388 {
389         return register_port (type, portname, false, async, extra_flags);
390 }
391
392 int
393 PortManager::unregister_port (boost::shared_ptr<Port> port)
394 {
395         /* This is a little subtle. We do not call the backend's port
396          * unregistration code from here. That is left for the Port
397          * destructor. We are trying to drop references to the Port object
398          * here, so that its destructor will run and it will unregister itself.
399          */
400
401         /* caller must hold process lock */
402
403         {
404                 RCUWriter<Ports> writer (ports);
405                 boost::shared_ptr<Ports> ps = writer.get_copy ();
406                 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
407
408                 if (x != ps->end()) {
409                         ps->erase (x);
410                 }
411
412                 /* writer goes out of scope, forces update */
413         }
414
415         ports.flush ();
416
417         return 0;
418 }
419
420 bool
421 PortManager::connected (const string& port_name)
422 {
423         if (!_backend) {
424                 return false;
425         }
426
427         PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
428
429         if (!handle) {
430                 return false;
431         }
432
433         return _backend->connected (handle);
434 }
435
436 bool
437 PortManager::physically_connected (const string& port_name)
438 {
439         if (!_backend) {
440                 return false;
441         }
442
443         PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
444
445         if (!handle) {
446                 return false;
447         }
448
449         return _backend->physically_connected (handle);
450 }
451
452 int
453 PortManager::get_connections (const string& port_name, std::vector<std::string>& s)
454 {
455         if (!_backend) {
456                 s.clear ();
457                 return 0;
458         }
459
460         PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
461
462         if (!handle) {
463                 s.clear ();
464                 return 0;
465         }
466
467         return _backend->get_connections (handle, s);
468 }
469
470 int
471 PortManager::connect (const string& source, const string& destination)
472 {
473         int ret;
474
475         string s = make_port_name_non_relative (source);
476         string d = make_port_name_non_relative (destination);
477
478         boost::shared_ptr<Port> src = get_port_by_name (s);
479         boost::shared_ptr<Port> dst = get_port_by_name (d);
480
481         if (src) {
482                 ret = src->connect (d);
483         } else if (dst) {
484                 ret = dst->connect (s);
485         } else {
486                 /* neither port is known to us ...hand-off to the PortEngine
487                  */
488                 if (_backend) {
489                         ret = _backend->connect (s, d);
490                 } else {
491                         ret = -1;
492                 }
493         }
494
495         if (ret > 0) {
496                 /* already exists - no error, no warning */
497         } else if (ret < 0) {
498                 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
499                                         source, s, destination, d)
500                       << endmsg;
501         }
502
503         return ret;
504 }
505
506 int
507 PortManager::disconnect (const string& source, const string& destination)
508 {
509         int ret;
510
511         string s = make_port_name_non_relative (source);
512         string d = make_port_name_non_relative (destination);
513
514         boost::shared_ptr<Port> src = get_port_by_name (s);
515         boost::shared_ptr<Port> dst = get_port_by_name (d);
516
517         if (src) {
518                 ret = src->disconnect (d);
519         } else if (dst) {
520                 ret = dst->disconnect (s);
521         } else {
522                 /* neither port is known to us ...hand-off to the PortEngine
523                  */
524                 if (_backend) {
525                         ret = _backend->disconnect (s, d);
526                 } else {
527                         ret = -1;
528                 }
529         }
530         return ret;
531 }
532
533 int
534 PortManager::disconnect (boost::shared_ptr<Port> port)
535 {
536         return port->disconnect_all ();
537 }
538
539 int
540 PortManager::reestablish_ports ()
541 {
542         Ports::iterator i;
543
544         boost::shared_ptr<Ports> p = ports.reader ();
545
546         DEBUG_TRACE (DEBUG::Ports, string_compose ("reestablish %1 ports\n", p->size()));
547
548         for (i = p->begin(); i != p->end(); ++i) {
549                 if (i->second->reestablish ()) {
550                         error << string_compose (_("Re-establising port %1 failed"), i->second->name()) << endmsg;
551                         std::cerr << string_compose (_("Re-establising port %1 failed"), i->second->name()) << std::endl;
552                         break;
553                 }
554         }
555
556         if (i != p->end()) {
557                 /* failed */
558                 remove_all_ports ();
559                 return -1;
560         }
561
562         return 0;
563 }
564
565 int
566 PortManager::reconnect_ports ()
567 {
568         boost::shared_ptr<Ports> p = ports.reader ();
569
570         if (!Profile->get_trx()) {
571                 /* re-establish connections */
572
573                 DEBUG_TRACE (DEBUG::Ports, string_compose ("reconnect %1 ports\n", p->size()));
574
575                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
576                         i->second->reconnect ();
577                 }
578         }
579
580         return 0;
581 }
582
583 void
584 PortManager::connect_callback (const string& a, const string& b, bool conn)
585 {
586         boost::shared_ptr<Port> port_a;
587         boost::shared_ptr<Port> port_b;
588         Ports::iterator x;
589         boost::shared_ptr<Ports> pr = ports.reader ();
590
591         x = pr->find (make_port_name_relative (a));
592         if (x != pr->end()) {
593                 port_a = x->second;
594         }
595
596         x = pr->find (make_port_name_relative (b));
597         if (x != pr->end()) {
598                 port_b = x->second;
599         }
600
601         PortConnectedOrDisconnected (
602                 port_a, a,
603                 port_b, b,
604                 conn
605                 ); /* EMIT SIGNAL */
606 }
607
608 void
609 PortManager::registration_callback ()
610 {
611         if (!_port_remove_in_progress) {
612                 PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
613         }
614 }
615
616 bool
617 PortManager::can_request_input_monitoring () const
618 {
619         if (!_backend) {
620                 return false;
621         }
622
623         return _backend->can_monitor_input ();
624 }
625
626 void
627 PortManager::request_input_monitoring (const string& name, bool yn) const
628 {
629         if (!_backend) {
630                 return;
631         }
632
633         PortEngine::PortHandle ph = _backend->get_port_by_name (name);
634
635         if (ph) {
636                 _backend->request_input_monitoring (ph, yn);
637         }
638 }
639
640 void
641 PortManager::ensure_input_monitoring (const string& name, bool yn) const
642 {
643         if (!_backend) {
644                 return;
645         }
646
647         PortEngine::PortHandle ph = _backend->get_port_by_name (name);
648
649         if (ph) {
650                 _backend->ensure_input_monitoring (ph, yn);
651         }
652 }
653
654 uint32_t
655 PortManager::port_name_size() const
656 {
657         if (!_backend) {
658                 return 0;
659         }
660
661         return _backend->port_name_size ();
662 }
663
664 string
665 PortManager::my_name() const
666 {
667         if (!_backend) {
668                 return string();
669         }
670
671         return _backend->my_name();
672 }
673
674 int
675 PortManager::graph_order_callback ()
676 {
677         if (!_port_remove_in_progress) {
678                 GraphReordered(); /* EMIT SIGNAL */
679         }
680
681         return 0;
682 }
683
684 void
685 PortManager::cycle_start (pframes_t nframes)
686 {
687         Port::set_global_port_buffer_offset (0);
688         Port::set_cycle_framecnt (nframes);
689
690         _cycle_ports = ports.reader ();
691
692         for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
693                 p->second->cycle_start (nframes);
694         }
695 }
696
697 void
698 PortManager::cycle_end (pframes_t nframes)
699 {
700         for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
701                 p->second->cycle_end (nframes);
702         }
703
704         for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
705                 p->second->flush_buffers (nframes);
706         }
707
708         _cycle_ports.reset ();
709
710         /* we are done */
711 }
712
713 void
714 PortManager::silence (pframes_t nframes, Session *s)
715 {
716         for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
717                 if (s && i->second == s->mtc_output_port ()) {
718                         continue;
719                 }
720                 if (s && i->second == s->midi_clock_output_port ()) {
721                         continue;
722                 }
723                 if (s && i->second == s->ltc_output_port ()) {
724                         continue;
725                 }
726                 if (boost::dynamic_pointer_cast<AsyncMIDIPort>(i->second)) {
727                         continue;
728                 }
729                 if (i->second->sends_output()) {
730                         i->second->get_buffer(nframes).silence(nframes);
731                 }
732         }
733 }
734
735 void
736 PortManager::silence_outputs (pframes_t nframes)
737 {
738         std::vector<std::string> port_names;
739         if (get_ports("", DataType::AUDIO, IsOutput, port_names)) {
740                 for (std::vector<std::string>::iterator p = port_names.begin(); p != port_names.end(); ++p) {
741                         if (!port_is_mine(*p)) {
742                                 continue;
743                         }
744                         PortEngine::PortHandle ph = _backend->get_port_by_name (*p);
745                         if (!ph) {
746                                 continue;
747                         }
748                         void *buf = _backend->get_buffer(ph, nframes);
749                         if (!buf) {
750                                 continue;
751                         }
752                         memset (buf, 0, sizeof(float) * nframes);
753                 }
754         }
755
756         if (get_ports("", DataType::MIDI, IsOutput, port_names)) {
757                 for (std::vector<std::string>::iterator p = port_names.begin(); p != port_names.end(); ++p) {
758                         if (!port_is_mine(*p)) {
759                                 continue;
760                         }
761                         PortEngine::PortHandle ph = _backend->get_port_by_name (*p);
762                         if (!ph) {
763                                 continue;
764                         }
765                         void *buf = _backend->get_buffer(ph, nframes);
766                         if (!buf) {
767                                 continue;
768                         }
769                         _backend->midi_clear (buf);
770                 }
771         }
772 }
773
774 void
775 PortManager::check_monitoring ()
776 {
777         for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
778
779                 bool x;
780
781                 if (i->second->last_monitor() != (x = i->second->monitoring_input ())) {
782                         i->second->set_last_monitor (x);
783                         /* XXX I think this is dangerous, due to
784                            a likely mutex in the signal handlers ...
785                         */
786                         i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
787                 }
788         }
789 }
790
791 void
792 PortManager::fade_out (gain_t base_gain, gain_t gain_step, pframes_t nframes)
793 {
794         for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
795
796                 if (i->second->sends_output()) {
797
798                         boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
799                         if (ap) {
800                                 Sample* s = ap->engine_get_whole_audio_buffer ();
801                                 gain_t g = base_gain;
802
803                                 for (pframes_t n = 0; n < nframes; ++n) {
804                                         *s++ *= g;
805                                         g -= gain_step;
806                                 }
807                         }
808                 }
809         }
810 }
811
812 PortEngine&
813 PortManager::port_engine()
814 {
815         assert (_backend);
816         return *_backend;
817 }
818
819 bool
820 PortManager::port_is_control_only (std::string const& name)
821 {
822         static regex_t compiled_pattern;
823         static string pattern;
824
825         if (pattern.empty()) {
826
827                 /* This is a list of regular expressions that match ports
828                  * related to physical MIDI devices that we do not want to
829                  * expose as normal physical ports.
830                  */
831
832                 const char * const control_only_ports[] = {
833                         X_(".*Ableton Push.*"),
834                         X_(".*FaderPort .*"),
835                 };
836
837                 pattern = "(";
838                 for (size_t n = 0; n < sizeof (control_only_ports)/sizeof (control_only_ports[0]); ++n) {
839                         if (n > 0) {
840                                 pattern += '|';
841                         }
842                         pattern += control_only_ports[n];
843                 }
844                 pattern += ')';
845
846                 regcomp (&compiled_pattern, pattern.c_str(), REG_EXTENDED|REG_NOSUB);
847         }
848
849         return regexec (&compiled_pattern, name.c_str(), 0, 0, 0) == 0;
850 }