merge fix for tempo branch
[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/error.h"
21
22 #include "ardour/async_midi_port.h"
23 #include "ardour/audio_backend.h"
24 #include "ardour/audio_port.h"
25 #include "ardour/debug.h"
26 #include "ardour/midi_port.h"
27 #include "ardour/midiport_manager.h"
28 #include "ardour/port_manager.h"
29
30 #include "i18n.h"
31
32 using namespace ARDOUR;
33 using namespace PBD;
34 using std::string;
35 using std::vector;
36
37 PortManager::PortManager ()
38         : ports (new Ports)
39         , _port_remove_in_progress (false)
40 {
41 }
42
43 void
44 PortManager::remove_all_ports ()
45 {
46         /* make sure that JACK callbacks that will be invoked as we cleanup
47          * ports know that they have nothing to do.
48          */
49
50         _port_remove_in_progress = true;
51
52         /* process lock MUST be held by caller
53         */
54
55         {
56                 RCUWriter<Ports> writer (ports);
57                 boost::shared_ptr<Ports> ps = writer.get_copy ();
58                 ps->clear ();
59         }
60
61         /* clear dead wood list in RCU */
62
63         ports.flush ();
64
65         _port_remove_in_progress = false;
66 }
67
68
69 string
70 PortManager::make_port_name_relative (const string& portname) const
71 {
72         if (!_backend) {
73                 return portname;
74         }
75
76         string::size_type len;
77         string::size_type n;
78         string self = _backend->my_name();
79
80         len = portname.length();
81
82         for (n = 0; n < len; ++n) {
83                 if (portname[n] == ':') {
84                         break;
85                 }
86         }
87
88         if ((n != len) && (portname.substr (0, n) == self)) {
89                 return portname.substr (n+1);
90         }
91
92         return portname;
93 }
94
95 string
96 PortManager::make_port_name_non_relative (const string& portname) const
97 {
98         string str;
99
100         if (portname.find_first_of (':') != string::npos) {
101                 return portname;
102         }
103
104         str  = _backend->my_name();
105         str += ':';
106         str += portname;
107
108         return str;
109 }
110
111 std::string
112 PortManager::get_pretty_name_by_name(const std::string& portname) const
113 {
114         PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
115         if (ph) {
116                 std::string value;
117                 std::string type;
118                 if (0 == _backend->get_port_property (ph,
119                                         "http://jackaudio.org/metadata/pretty-name",
120                                         value, type))
121                 {
122                         return value;
123                 }
124         }
125         return "";
126 }
127
128 bool
129 PortManager::port_is_mine (const string& portname) const
130 {
131         if (!_backend) {
132                 return true;
133         }
134
135         string self = _backend->my_name();
136
137         if (portname.find_first_of (':') != string::npos) {
138                 if (portname.substr (0, self.length ()) != self) {
139                         return false;
140                 }
141         }
142
143         return true;
144 }
145
146 bool
147 PortManager::port_is_physical (const std::string& portname) const
148 {
149         if (!_backend) {
150                 return false;
151         }
152
153         PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
154         if (!ph) {
155                 return false;
156         }
157
158         return _backend->port_is_physical (ph);
159 }
160
161 void
162 PortManager::get_physical_outputs (DataType type, std::vector<std::string>& s)
163 {
164         if (!_backend) {
165                 return;
166         }
167         _backend->get_physical_outputs (type, s);
168 }
169  
170 void
171 PortManager::get_physical_inputs (DataType type, std::vector<std::string>& s)
172 {
173         if (!_backend) {
174                 return;
175         }
176
177         _backend->get_physical_inputs (type, s);
178 }
179  
180 ChanCount
181 PortManager::n_physical_outputs () const
182 {
183         if (!_backend) {
184                 return ChanCount::ZERO;
185         }
186
187         return _backend->n_physical_outputs ();
188 }
189  
190 ChanCount
191 PortManager::n_physical_inputs () const
192 {
193         if (!_backend) {
194                 return ChanCount::ZERO;
195         }
196         return _backend->n_physical_inputs ();
197 }
198
199 /** @param name Full or short name of port
200  *  @return Corresponding Port or 0.
201  */
202
203 boost::shared_ptr<Port>
204 PortManager::get_port_by_name (const string& portname)
205 {
206         if (!_backend) {
207                 return boost::shared_ptr<Port>();
208         }
209
210         if (!port_is_mine (portname)) {
211                 /* not an ardour port */
212                 return boost::shared_ptr<Port> ();
213         }
214
215         boost::shared_ptr<Ports> pr = ports.reader();
216         std::string rel = make_port_name_relative (portname);
217         Ports::iterator x = pr->find (rel);
218
219         if (x != pr->end()) {
220                 /* its possible that the port was renamed by some 3rd party and
221                    we don't know about it. check for this (the check is quick
222                    and cheap), and if so, rename the port (which will alter
223                    the port map as a side effect).
224                 */
225                 const std::string check = make_port_name_relative (_backend->get_port_name (x->second->port_handle()));
226                 if (check != rel) {
227                         x->second->set_name (check);
228                 }
229                 return x->second;
230         }
231
232         return boost::shared_ptr<Port> ();
233 }
234
235 void
236 PortManager::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
237 {
238         RCUWriter<Ports> writer (ports);
239         boost::shared_ptr<Ports> p = writer.get_copy();
240         Ports::iterator x = p->find (old_relative_name);
241         
242         if (x != p->end()) {
243                 boost::shared_ptr<Port> port = x->second;
244                 p->erase (x);
245                 p->insert (make_pair (new_relative_name, port));
246         }
247 }
248
249 int
250 PortManager::get_ports (DataType type, PortList& pl)
251 {
252         boost::shared_ptr<Ports> plist = ports.reader();
253         for (Ports::iterator p = plist->begin(); p != plist->end(); ++p) {
254                 if (p->second->type() == type) {
255                         pl.push_back (p->second);
256                 }
257         }
258         return pl.size();
259 }
260
261 int
262 PortManager::get_ports (const string& port_name_pattern, DataType type, PortFlags flags, vector<string>& s)
263 {
264         if (!_backend) {
265                 return 0;
266         }
267
268         return _backend->get_ports (port_name_pattern, type, flags, s);
269 }
270
271 void
272 PortManager::port_registration_failure (const std::string& portname)
273 {
274         if (!_backend) {
275                 return;
276         }
277
278         string full_portname = _backend->my_name();
279         full_portname += ':';
280         full_portname += portname;
281
282
283         PortEngine::PortHandle p = _backend->get_port_by_name (full_portname);
284         string reason;
285
286         if (p) {
287                 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
288         } else {
289                 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);
290         }
291
292         throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
293 }
294
295 boost::shared_ptr<Port>
296 PortManager::register_port (DataType dtype, const string& portname, bool input, bool async)
297 {
298         boost::shared_ptr<Port> newport;
299
300         try {
301                 if (dtype == DataType::AUDIO) {
302                         DEBUG_TRACE (DEBUG::Ports, string_compose ("registering AUDIO port %1, input %2\n",
303                                                                    portname, input));
304                         newport.reset (new AudioPort (portname, (input ? IsInput : IsOutput)));
305                 } else if (dtype == DataType::MIDI) {
306                         if (async) {
307                                 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering ASYNC MIDI port %1, input %2\n",
308                                                                            portname, input));
309                                 newport.reset (new AsyncMIDIPort (portname, (input ? IsInput : IsOutput)));
310                         } else {
311                                 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering MIDI port %1, input %2\n",
312                                                                            portname, input));
313                                 newport.reset (new MidiPort (portname, (input ? IsInput : IsOutput)));
314                         }
315                 } else {
316                         throw PortRegistrationFailure("unable to create port (unknown type)");
317                 }
318
319                 RCUWriter<Ports> writer (ports);
320                 boost::shared_ptr<Ports> ps = writer.get_copy ();
321                 ps->insert (make_pair (make_port_name_relative (portname), newport));
322
323                 /* writer goes out of scope, forces update */
324
325         }
326
327         catch (PortRegistrationFailure& err) {
328                 throw err;
329         } catch (std::exception& e) {
330                 throw PortRegistrationFailure(string_compose(
331                                 _("unable to create port: %1"), e.what()).c_str());
332         } catch (...) {
333                 throw PortRegistrationFailure("unable to create port (unknown error)");
334         }
335
336         DEBUG_TRACE (DEBUG::Ports, string_compose ("\t%2 port registration success, ports now = %1\n", ports.reader()->size(), this));
337         return newport;
338 }
339
340 boost::shared_ptr<Port>
341 PortManager::register_input_port (DataType type, const string& portname, bool async)
342 {
343         return register_port (type, portname, true, async);
344 }
345
346 boost::shared_ptr<Port>
347 PortManager::register_output_port (DataType type, const string& portname, bool async)
348 {
349         return register_port (type, portname, false, async);
350 }
351
352 int
353 PortManager::unregister_port (boost::shared_ptr<Port> port)
354 {
355         /* caller must hold process lock */
356
357         {
358                 RCUWriter<Ports> writer (ports);
359                 boost::shared_ptr<Ports> ps = writer.get_copy ();
360                 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
361
362                 if (x != ps->end()) {
363                         ps->erase (x);
364                 }
365
366                 /* writer goes out of scope, forces update */
367         }
368
369         ports.flush ();
370
371         return 0;
372 }
373
374 bool
375 PortManager::connected (const string& port_name)
376 {
377         if (!_backend) {
378                 return false;
379         }
380
381         PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
382
383         if (!handle) {
384                 return false;
385         }
386
387         return _backend->connected (handle);
388 }
389
390 int
391 PortManager::connect (const string& source, const string& destination)
392 {
393         int ret;
394
395         string s = make_port_name_non_relative (source);
396         string d = make_port_name_non_relative (destination);
397
398         boost::shared_ptr<Port> src = get_port_by_name (s);
399         boost::shared_ptr<Port> dst = get_port_by_name (d);
400
401         if (src) {
402                 ret = src->connect (d);
403         } else if (dst) {
404                 ret = dst->connect (s);
405         } else {
406                 /* neither port is known to us ...hand-off to the PortEngine
407                  */
408                 if (_backend) {
409                         ret = _backend->connect (s, d);
410                 } else {
411                         ret = -1;
412                 }
413         }
414
415         if (ret > 0) {
416                 /* already exists - no error, no warning */
417         } else if (ret < 0) {
418                 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
419                                         source, s, destination, d)
420                       << endmsg;
421         }
422
423         return ret;
424 }
425
426 int
427 PortManager::disconnect (const string& source, const string& destination)
428 {
429         int ret;
430
431         string s = make_port_name_non_relative (source);
432         string d = make_port_name_non_relative (destination);
433
434         boost::shared_ptr<Port> src = get_port_by_name (s);
435         boost::shared_ptr<Port> dst = get_port_by_name (d);
436
437         if (src) {
438                 ret = src->disconnect (d);
439         } else if (dst) {
440                 ret = dst->disconnect (s);
441         } else {
442                 /* neither port is known to us ...hand-off to the PortEngine
443                  */
444                 if (_backend) {
445                         ret = _backend->disconnect (s, d);
446                 } else {
447                         ret = -1;
448                 }
449         }
450         return ret;
451 }
452
453 int
454 PortManager::disconnect (boost::shared_ptr<Port> port)
455 {
456         return port->disconnect_all ();
457 }
458
459 int
460 PortManager::reestablish_ports ()
461 {
462         Ports::iterator i;
463
464         boost::shared_ptr<Ports> p = ports.reader ();
465
466         DEBUG_TRACE (DEBUG::Ports, string_compose ("reestablish %1 ports\n", p->size()));
467
468         for (i = p->begin(); i != p->end(); ++i) {
469                 if (i->second->reestablish ()) {
470                         error << string_compose (_("Re-establising port %1 failed"), i->second->name()) << endmsg;
471                         std::cerr << string_compose (_("Re-establising port %1 failed"), i->second->name()) << std::endl;
472                         break;
473                 }
474         }
475
476         if (i != p->end()) {
477                 /* failed */
478                 remove_all_ports ();
479                 return -1;
480         }
481
482         return 0;
483 }
484
485 int
486 PortManager::reconnect_ports ()
487 {
488         boost::shared_ptr<Ports> p = ports.reader ();
489
490         /* re-establish connections */
491
492         DEBUG_TRACE (DEBUG::Ports, string_compose ("reconnect %1 ports\n", p->size()));
493
494         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
495                 i->second->reconnect ();
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::check_monitoring ()
643 {
644         for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
645                 
646                 bool x;
647                 
648                 if (i->second->last_monitor() != (x = i->second->monitoring_input ())) {
649                         i->second->set_last_monitor (x);
650                         /* XXX I think this is dangerous, due to
651                            a likely mutex in the signal handlers ...
652                         */
653                         i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
654                 }
655         }
656 }
657
658 void
659 PortManager::fade_out (gain_t base_gain, gain_t gain_step, pframes_t nframes)
660 {
661         for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
662                 
663                 if (i->second->sends_output()) {
664                         
665                         boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
666                         if (ap) {
667                                 Sample* s = ap->engine_get_whole_audio_buffer ();
668                                 gain_t g = base_gain;
669                                 
670                                 for (pframes_t n = 0; n < nframes; ++n) {
671                                         *s++ *= g;
672                                         g -= gain_step;
673                                 }
674                         }
675                 }
676         }
677 }
678
679 PortEngine&
680 PortManager::port_engine()
681 {
682         assert (_backend);
683         return *_backend;
684 }