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