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