redesign naming and reload of MIDI port information (library edition)
[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 <vector>
21
22 #ifdef COMPILER_MSVC
23 #include <io.h> // Microsoft's nearest equivalent to <unistd.h>
24 #include <ardourext/misc.h>
25 #else
26 #include <regex.h>
27 #endif
28
29 #include <glibmm/fileutils.h>
30 #include <glibmm/miscutils.h>
31
32 #include "pbd/error.h"
33 #include "pbd/strsplit.h"
34
35 #include "ardour/async_midi_port.h"
36 #include "ardour/audio_backend.h"
37 #include "ardour/audio_port.h"
38 #include "ardour/debug.h"
39 #include "ardour/filesystem_paths.h"
40 #include "ardour/midi_port.h"
41 #include "ardour/midiport_manager.h"
42 #include "ardour/port_manager.h"
43 #include "ardour/profile.h"
44 #include "ardour/rt_tasklist.h"
45 #include "ardour/session.h"
46 #include "ardour/types_convert.h"
47
48 #include "pbd/i18n.h"
49
50 using namespace ARDOUR;
51 using namespace PBD;
52 using std::string;
53 using std::vector;
54
55 #define MIDI_PORT_INFO_SEPARATOR_CHAR '!'
56
57 PortManager::PortManager ()
58         : ports (new Ports)
59         , _port_remove_in_progress (false)
60         , _port_deletions_pending (8192) /* ick, arbitrary sizing */
61         , midi_info_dirty (true)
62 {
63         load_midi_port_info ();
64 }
65
66 void
67 PortManager::clear_pending_port_deletions ()
68 {
69         Port* p;
70
71         DEBUG_TRACE (DEBUG::Ports, string_compose ("pending port deletions: %1\n", _port_deletions_pending.read_space()));
72
73         while (_port_deletions_pending.read (&p, 1) == 1) {
74                 delete p;
75         }
76 }
77
78 void
79 PortManager::remove_all_ports ()
80 {
81         /* make sure that JACK callbacks that will be invoked as we cleanup
82          * ports know that they have nothing to do.
83          */
84
85         _port_remove_in_progress = true;
86
87         /* process lock MUST be held by caller
88         */
89
90         {
91                 RCUWriter<Ports> writer (ports);
92                 boost::shared_ptr<Ports> ps = writer.get_copy ();
93                 ps->clear ();
94         }
95
96         /* clear dead wood list in RCU */
97
98         ports.flush ();
99
100         /* clear out pending port deletion list. we know this is safe because
101          * the auto connect thread in Session is already dead when this is
102          * done. It doesn't use shared_ptr<Port> anyway.
103          */
104
105         _port_deletions_pending.reset ();
106
107         _port_remove_in_progress = false;
108 }
109
110
111 string
112 PortManager::make_port_name_relative (const string& portname) const
113 {
114         if (!_backend) {
115                 return portname;
116         }
117
118         string::size_type colon = portname.find (':');
119
120         if (colon == string::npos) {
121                 return portname;
122         }
123
124         if (portname.substr (0, colon) == _backend->my_name()) {
125                 return portname.substr (colon+1);
126         }
127
128         return portname;
129 }
130
131 string
132 PortManager::make_port_name_non_relative (const string& portname) const
133 {
134         string str;
135
136         if (portname.find_first_of (':') != string::npos) {
137                 return portname;
138         }
139
140         str  = _backend->my_name();
141         str += ':';
142         str += portname;
143
144         return str;
145 }
146
147 std::string
148 PortManager::get_pretty_name_by_name(const std::string& portname) const
149 {
150         PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
151
152         if (ph) {
153                 std::string value;
154                 std::string type;
155                 if (0 == _backend->get_port_property (ph, "http://jackaudio.org/metadata/pretty-name", value, type)) {
156                         return value;
157                 }
158         }
159
160         return string();
161 }
162
163 bool
164 PortManager::port_is_mine (const string& portname) const
165 {
166         if (!_backend) {
167                 return true;
168         }
169
170         string self = _backend->my_name();
171
172         if (portname.find_first_of (':') != string::npos) {
173                 if (portname.substr (0, self.length ()) != self) {
174                         return false;
175                 }
176         }
177
178         return true;
179 }
180
181 bool
182 PortManager::port_is_physical (const std::string& portname) const
183 {
184         if (!_backend) {
185                 return false;
186         }
187
188         PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
189         if (!ph) {
190                 return false;
191         }
192
193         return _backend->port_is_physical (ph);
194 }
195
196 void
197 PortManager::filter_midi_ports (vector<string>& ports, MidiPortFlags include, MidiPortFlags exclude)
198 {
199
200         if (!include && !exclude) {
201                 return;
202         }
203
204         {
205                 Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
206
207                 fill_midi_port_info_locked ();
208
209                 for (vector<string>::iterator si = ports.begin(); si != ports.end(); ) {
210
211                         MidiPortInfo::iterator x = midi_port_info.find (*si);
212
213                         if (x == midi_port_info.end()) {
214                                 ++si;
215                                 continue;
216                         }
217
218                         MidiPortInformation& mpi (x->second);
219
220                         if (mpi.pretty_name.empty()) {
221                                 /* no information !!! */
222                                 ++si;
223                                 continue;
224                         }
225
226                         if (include) {
227                                 if ((mpi.properties & include) != include) {
228                                         /* properties do not include requested ones */
229                                         si = ports.erase (si);
230                                         continue;
231                                 }
232                         }
233
234                         if (exclude) {
235                                 if ((mpi.properties & exclude)) {
236                                         /* properties include ones to avoid */
237                                         si = ports.erase (si);
238                                         continue;
239                                 }
240                         }
241
242                         ++si;
243                 }
244         }
245 }
246
247 void
248 PortManager::get_physical_outputs (DataType type, std::vector<std::string>& s, MidiPortFlags include, MidiPortFlags exclude)
249 {
250         if (!_backend) {
251                 s.clear ();
252                 return;
253         }
254         _backend->get_physical_outputs (type, s);
255         filter_midi_ports (s, include, exclude);
256 }
257
258 void
259 PortManager::get_physical_inputs (DataType type, std::vector<std::string>& s, MidiPortFlags include, MidiPortFlags exclude)
260 {
261         if (!_backend) {
262                 s.clear ();
263                 return;
264         }
265
266         _backend->get_physical_inputs (type, s);
267         filter_midi_ports (s, include, exclude);
268 }
269
270 ChanCount
271 PortManager::n_physical_outputs () const
272 {
273         if (!_backend) {
274                 return ChanCount::ZERO;
275         }
276
277         return _backend->n_physical_outputs ();
278 }
279
280 ChanCount
281 PortManager::n_physical_inputs () const
282 {
283         if (!_backend) {
284                 return ChanCount::ZERO;
285         }
286         return _backend->n_physical_inputs ();
287 }
288
289 /** @param name Full or short name of port
290  *  @return Corresponding Port or 0.
291  */
292 boost::shared_ptr<Port>
293 PortManager::get_port_by_name (const string& portname)
294 {
295         if (!_backend) {
296                 return boost::shared_ptr<Port>();
297         }
298
299         if (!port_is_mine (portname)) {
300                 /* not an ardour port */
301                 return boost::shared_ptr<Port> ();
302         }
303
304         boost::shared_ptr<Ports> pr = ports.reader();
305         std::string rel = make_port_name_relative (portname);
306         Ports::iterator x = pr->find (rel);
307
308         if (x != pr->end()) {
309                 /* its possible that the port was renamed by some 3rd party and
310                  * we don't know about it. check for this (the check is quick
311                  * and cheap), and if so, rename the port (which will alter
312                  * the port map as a side effect).
313                  */
314                 const std::string check = make_port_name_relative (_backend->get_port_name (x->second->port_handle()));
315                 if (check != rel) {
316                         x->second->set_name (check);
317                 }
318                 return x->second;
319         }
320
321         return boost::shared_ptr<Port> ();
322 }
323
324 void
325 PortManager::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
326 {
327         RCUWriter<Ports> writer (ports);
328         boost::shared_ptr<Ports> p = writer.get_copy();
329         Ports::iterator x = p->find (old_relative_name);
330
331         if (x != p->end()) {
332                 boost::shared_ptr<Port> port = x->second;
333                 p->erase (x);
334                 p->insert (make_pair (new_relative_name, port));
335         }
336 }
337
338 int
339 PortManager::get_ports (DataType type, PortList& pl)
340 {
341         boost::shared_ptr<Ports> plist = ports.reader();
342         for (Ports::iterator p = plist->begin(); p != plist->end(); ++p) {
343                 if (p->second->type() == type) {
344                         pl.push_back (p->second);
345                 }
346         }
347         return pl.size();
348 }
349
350 int
351 PortManager::get_ports (const string& port_name_pattern, DataType type, PortFlags flags, vector<string>& s)
352 {
353         s.clear();
354
355         if (!_backend) {
356                 return 0;
357         }
358
359         return _backend->get_ports (port_name_pattern, type, flags, s);
360 }
361
362 void
363 PortManager::port_registration_failure (const std::string& portname)
364 {
365         if (!_backend) {
366                 return;
367         }
368
369         string full_portname = _backend->my_name();
370         full_portname += ':';
371         full_portname += portname;
372
373
374         PortEngine::PortHandle p = _backend->get_port_by_name (full_portname);
375         string reason;
376
377         if (p) {
378                 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
379         } else {
380                 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);
381         }
382
383         throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
384 }
385
386 struct PortDeleter
387 {
388         void operator() (Port* p) {
389                 AudioEngine::instance()->add_pending_port_deletion (p);
390         }
391 };
392
393 boost::shared_ptr<Port>
394 PortManager::register_port (DataType dtype, const string& portname, bool input, bool async, PortFlags flags)
395 {
396         boost::shared_ptr<Port> newport;
397
398         /* limit the possible flags that can be set */
399
400         flags = PortFlags (flags & (Hidden|Shadow|IsTerminal));
401
402         try {
403                 if (dtype == DataType::AUDIO) {
404                         DEBUG_TRACE (DEBUG::Ports, string_compose ("registering AUDIO port %1, input %2\n",
405                                                                    portname, input));
406                         newport.reset (new AudioPort (portname, PortFlags ((input ? IsInput : IsOutput) | flags)),
407                                        PortDeleter());
408                 } else if (dtype == DataType::MIDI) {
409                         if (async) {
410                                 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering ASYNC MIDI port %1, input %2\n",
411                                                                            portname, input));
412                                 newport.reset (new AsyncMIDIPort (portname, PortFlags ((input ? IsInput : IsOutput) | flags)),
413                                                PortDeleter());
414                         } else {
415                                 DEBUG_TRACE (DEBUG::Ports, string_compose ("registering MIDI port %1, input %2\n",
416                                                                            portname, input));
417                                 newport.reset (new MidiPort (portname, PortFlags ((input ? IsInput : IsOutput) | flags)),
418                                                PortDeleter());
419                         }
420                 } else {
421                         throw PortRegistrationFailure (string_compose ("unable to create port '%1': %2", portname, _("(unknown type)")));
422                 }
423
424                 RCUWriter<Ports> writer (ports);
425                 boost::shared_ptr<Ports> ps = writer.get_copy ();
426                 ps->insert (make_pair (make_port_name_relative (portname), newport));
427
428                 /* writer goes out of scope, forces update */
429
430         }
431
432         catch (PortRegistrationFailure& err) {
433                 throw err;
434         } catch (std::exception& e) {
435                 throw PortRegistrationFailure (string_compose ("unable to create port '%1': %2", portname, e.what()).c_str());
436         } catch (...) {
437                 throw PortRegistrationFailure (string_compose ("unable to create port '%1': %2", portname, _("(unknown error)")));
438         }
439
440         DEBUG_TRACE (DEBUG::Ports, string_compose ("\t%2 port registration success, ports now = %1\n", ports.reader()->size(), this));
441         return newport;
442 }
443
444 boost::shared_ptr<Port>
445 PortManager::register_input_port (DataType type, const string& portname, bool async, PortFlags extra_flags)
446 {
447         return register_port (type, portname, true, async, extra_flags);
448 }
449
450 boost::shared_ptr<Port>
451 PortManager::register_output_port (DataType type, const string& portname, bool async, PortFlags extra_flags)
452 {
453         return register_port (type, portname, false, async, extra_flags);
454 }
455
456 int
457 PortManager::unregister_port (boost::shared_ptr<Port> port)
458 {
459         /* This is a little subtle. We do not call the backend's port
460          * unregistration code from here. That is left for the Port
461          * destructor. We are trying to drop references to the Port object
462          * here, so that its destructor will run and it will unregister itself.
463          */
464
465         /* caller must hold process lock */
466
467         {
468                 RCUWriter<Ports> writer (ports);
469                 boost::shared_ptr<Ports> ps = writer.get_copy ();
470                 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
471
472                 if (x != ps->end()) {
473                         DEBUG_TRACE (DEBUG::Ports, string_compose ("removing %1 from port map (uc=%2)\n", port->name(), port.use_count()));
474                         ps->erase (x);
475                 }
476
477                 /* writer goes out of scope, forces update */
478         }
479
480         ports.flush ();
481
482         return 0;
483 }
484
485 bool
486 PortManager::connected (const string& port_name)
487 {
488         if (!_backend) {
489                 return false;
490         }
491
492         PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
493
494         if (!handle) {
495                 return false;
496         }
497
498         return _backend->connected (handle);
499 }
500
501 bool
502 PortManager::physically_connected (const string& port_name)
503 {
504         if (!_backend) {
505                 return false;
506         }
507
508         PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
509
510         if (!handle) {
511                 return false;
512         }
513
514         return _backend->physically_connected (handle);
515 }
516
517 int
518 PortManager::get_connections (const string& port_name, std::vector<std::string>& s)
519 {
520         if (!_backend) {
521                 s.clear ();
522                 return 0;
523         }
524
525         PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
526
527         if (!handle) {
528                 s.clear ();
529                 return 0;
530         }
531
532         return _backend->get_connections (handle, s);
533 }
534
535 int
536 PortManager::connect (const string& source, const string& destination)
537 {
538         int ret;
539
540         string s = make_port_name_non_relative (source);
541         string d = make_port_name_non_relative (destination);
542
543         boost::shared_ptr<Port> src = get_port_by_name (s);
544         boost::shared_ptr<Port> dst = get_port_by_name (d);
545
546         if (src) {
547                 ret = src->connect (d);
548         } else if (dst) {
549                 ret = dst->connect (s);
550         } else {
551                 /* neither port is known to us ...hand-off to the PortEngine
552                  */
553                 if (_backend) {
554                         ret = _backend->connect (s, d);
555                 } else {
556                         ret = -1;
557                 }
558         }
559
560         if (ret > 0) {
561                 /* already exists - no error, no warning */
562         } else if (ret < 0) {
563                 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
564                                         source, s, destination, d)
565                       << endmsg;
566         }
567
568         return ret;
569 }
570
571 int
572 PortManager::disconnect (const string& source, const string& destination)
573 {
574         int ret;
575
576         string s = make_port_name_non_relative (source);
577         string d = make_port_name_non_relative (destination);
578
579         boost::shared_ptr<Port> src = get_port_by_name (s);
580         boost::shared_ptr<Port> dst = get_port_by_name (d);
581
582         if (src) {
583                 ret = src->disconnect (d);
584         } else if (dst) {
585                 ret = dst->disconnect (s);
586         } else {
587                 /* neither port is known to us ...hand-off to the PortEngine
588                  */
589                 if (_backend) {
590                         ret = _backend->disconnect (s, d);
591                 } else {
592                         ret = -1;
593                 }
594         }
595         return ret;
596 }
597
598 int
599 PortManager::disconnect (boost::shared_ptr<Port> port)
600 {
601         return port->disconnect_all ();
602 }
603
604 int
605 PortManager::disconnect (std::string const & name)
606 {
607         PortEngine::PortHandle ph = _backend->get_port_by_name (name);
608         if (ph) {
609                 return _backend->disconnect_all (ph);
610         }
611         return -2;
612 }
613
614 int
615 PortManager::reestablish_ports ()
616 {
617         Ports::iterator i;
618
619         boost::shared_ptr<Ports> p = ports.reader ();
620
621         DEBUG_TRACE (DEBUG::Ports, string_compose ("reestablish %1 ports\n", p->size()));
622
623         for (i = p->begin(); i != p->end(); ++i) {
624                 if (i->second->reestablish ()) {
625                         error << string_compose (_("Re-establising port %1 failed"), i->second->name()) << endmsg;
626                         std::cerr << string_compose (_("Re-establising port %1 failed"), i->second->name()) << std::endl;
627                         break;
628                 }
629         }
630
631         if (i != p->end()) {
632                 /* failed */
633                 remove_all_ports ();
634                 return -1;
635         }
636
637         return 0;
638 }
639
640 int
641 PortManager::reconnect_ports ()
642 {
643         boost::shared_ptr<Ports> p = ports.reader ();
644
645         if (!Profile->get_trx()) {
646                 /* re-establish connections */
647
648                 DEBUG_TRACE (DEBUG::Ports, string_compose ("reconnect %1 ports\n", p->size()));
649
650                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
651                         i->second->reconnect ();
652                 }
653         }
654
655         return 0;
656 }
657
658 void
659 PortManager::connect_callback (const string& a, const string& b, bool conn)
660 {
661         boost::shared_ptr<Port> port_a;
662         boost::shared_ptr<Port> port_b;
663         Ports::iterator x;
664         boost::shared_ptr<Ports> pr = ports.reader ();
665
666         x = pr->find (make_port_name_relative (a));
667         if (x != pr->end()) {
668                 port_a = x->second;
669         }
670
671         x = pr->find (make_port_name_relative (b));
672         if (x != pr->end()) {
673                 port_b = x->second;
674         }
675
676         if (conn) {
677                 if (port_a && !port_b) {
678                         port_a->increment_external_connections ();
679                 } else if (port_b && !port_a) {
680                         port_b->increment_external_connections ();
681                 }
682         } else {
683                 if (port_a && !port_b) {
684                         port_a->decrement_external_connections ();
685                 } else if (port_b && !port_a) {
686                         port_b->decrement_external_connections ();
687                 }
688         }
689
690         PortConnectedOrDisconnected (
691                 port_a, a,
692                 port_b, b,
693                 conn
694                 ); /* EMIT SIGNAL */
695 }
696
697 void
698 PortManager::registration_callback ()
699 {
700         if (!_port_remove_in_progress) {
701
702                 {
703                         Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
704                         midi_info_dirty = true;
705                 }
706
707                 PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
708         }
709 }
710
711 bool
712 PortManager::can_request_input_monitoring () const
713 {
714         if (!_backend) {
715                 return false;
716         }
717
718         return _backend->can_monitor_input ();
719 }
720
721 void
722 PortManager::request_input_monitoring (const string& name, bool yn) const
723 {
724         if (!_backend) {
725                 return;
726         }
727
728         PortEngine::PortHandle ph = _backend->get_port_by_name (name);
729
730         if (ph) {
731                 _backend->request_input_monitoring (ph, yn);
732         }
733 }
734
735 void
736 PortManager::ensure_input_monitoring (const string& name, bool yn) const
737 {
738         if (!_backend) {
739                 return;
740         }
741
742         PortEngine::PortHandle ph = _backend->get_port_by_name (name);
743
744         if (ph) {
745                 _backend->ensure_input_monitoring (ph, yn);
746         }
747 }
748
749 uint32_t
750 PortManager::port_name_size() const
751 {
752         if (!_backend) {
753                 return 0;
754         }
755
756         return _backend->port_name_size ();
757 }
758
759 string
760 PortManager::my_name() const
761 {
762         if (!_backend) {
763                 return string();
764         }
765
766         return _backend->my_name();
767 }
768
769 int
770 PortManager::graph_order_callback ()
771 {
772         if (!_port_remove_in_progress) {
773                 GraphReordered(); /* EMIT SIGNAL */
774         }
775
776         return 0;
777 }
778
779 void
780 PortManager::cycle_start (pframes_t nframes, Session* s)
781 {
782         Port::set_global_port_buffer_offset (0);
783         Port::set_cycle_samplecnt (nframes);
784
785         _cycle_ports = ports.reader ();
786
787         /* TODO optimize
788          *  - when speed == 1.0, the resampler copies data without processing
789          *   it may (or may not) be more efficient to just run all in sequence.
790          *
791          *  - single sequential task for 'lightweight' tasks would make sense
792          *    (run it in parallel with 'heavy' resampling.
793          *    * output ports (sends_output()) only set a flag
794          *    * midi-ports only scale event timestamps
795          *
796          *  - a threshold parallel vs searial processing may be appropriate.
797          *    amount of work (how many connected ports are there, how
798          *    many resamplers need to run) vs. available CPU cores and semaphore
799          *    synchronization overhead.
800          *
801          *  - input ports: it would make sense to resample each input only once
802          *    (rather than resample into each ardour-owned input port).
803          *    A single external source-port may be connected to many ardour
804          *    input-ports. Currently re-sampling is per input.
805          */
806         if (s && s->rt_tasklist () && fabs (Port::speed_ratio ()) != 1.0) {
807                 RTTaskList::TaskList tl;
808                 for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
809                         tl.push_back (boost::bind (&Port::cycle_start, p->second, nframes));
810                 }
811                 s->rt_tasklist()->process (tl);
812         } else {
813                 for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
814                         p->second->cycle_start (nframes);
815                 }
816         }
817 }
818
819 void
820 PortManager::cycle_end (pframes_t nframes, Session* s)
821 {
822         // see optimzation note in ::cycle_start()
823         if (s && s->rt_tasklist () && fabs (Port::speed_ratio ()) != 1.0) {
824                 RTTaskList::TaskList tl;
825                 for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
826                         tl.push_back (boost::bind (&Port::cycle_end, p->second, nframes));
827                 }
828                 s->rt_tasklist()->process (tl);
829         } else {
830                 for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
831                         p->second->cycle_end (nframes);
832                 }
833         }
834
835         for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
836                 p->second->flush_buffers (nframes);
837         }
838
839         _cycle_ports.reset ();
840
841         /* we are done */
842 }
843
844 void
845 PortManager::silence (pframes_t nframes, Session *s)
846 {
847         for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
848                 if (s && i->second == s->mtc_output_port ()) {
849                         continue;
850                 }
851                 if (s && i->second == s->midi_clock_output_port ()) {
852                         continue;
853                 }
854                 if (s && i->second == s->ltc_output_port ()) {
855                         continue;
856                 }
857                 if (boost::dynamic_pointer_cast<AsyncMIDIPort>(i->second)) {
858                         continue;
859                 }
860                 if (i->second->sends_output()) {
861                         i->second->get_buffer(nframes).silence(nframes);
862                 }
863         }
864 }
865
866 void
867 PortManager::silence_outputs (pframes_t nframes)
868 {
869         std::vector<std::string> port_names;
870         if (get_ports("", DataType::AUDIO, IsOutput, port_names)) {
871                 for (std::vector<std::string>::iterator p = port_names.begin(); p != port_names.end(); ++p) {
872                         if (!port_is_mine(*p)) {
873                                 continue;
874                         }
875                         PortEngine::PortHandle ph = _backend->get_port_by_name (*p);
876                         if (!ph) {
877                                 continue;
878                         }
879                         void *buf = _backend->get_buffer(ph, nframes);
880                         if (!buf) {
881                                 continue;
882                         }
883                         memset (buf, 0, sizeof(float) * nframes);
884                 }
885         }
886
887         if (get_ports("", DataType::MIDI, IsOutput, port_names)) {
888                 for (std::vector<std::string>::iterator p = port_names.begin(); p != port_names.end(); ++p) {
889                         if (!port_is_mine(*p)) {
890                                 continue;
891                         }
892                         PortEngine::PortHandle ph = _backend->get_port_by_name (*p);
893                         if (!ph) {
894                                 continue;
895                         }
896                         void *buf = _backend->get_buffer(ph, nframes);
897                         if (!buf) {
898                                 continue;
899                         }
900                         _backend->midi_clear (buf);
901                 }
902         }
903 }
904
905 void
906 PortManager::check_monitoring ()
907 {
908         for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
909
910                 bool x;
911
912                 if (i->second->last_monitor() != (x = i->second->monitoring_input ())) {
913                         i->second->set_last_monitor (x);
914                         /* XXX I think this is dangerous, due to
915                            a likely mutex in the signal handlers ...
916                         */
917                         i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
918                 }
919         }
920 }
921
922 void
923 PortManager::cycle_end_fade_out (gain_t base_gain, gain_t gain_step, pframes_t nframes, Session* s)
924 {
925         // see optimzation note in ::cycle_start()
926         if (s && s->rt_tasklist () && fabs (Port::speed_ratio ()) != 1.0) {
927                 RTTaskList::TaskList tl;
928                 for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
929                         tl.push_back (boost::bind (&Port::cycle_end, p->second, nframes));
930                 }
931                 s->rt_tasklist()->process (tl);
932         } else {
933                 for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
934                         p->second->cycle_end (nframes);
935                 }
936         }
937
938         for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
939                 p->second->flush_buffers (nframes);
940
941                 if (p->second->sends_output()) {
942
943                         boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (p->second);
944                         if (ap) {
945                                 Sample* s = ap->engine_get_whole_audio_buffer ();
946                                 gain_t g = base_gain;
947
948                                 for (pframes_t n = 0; n < nframes; ++n) {
949                                         *s++ *= g;
950                                         g -= gain_step;
951                                 }
952                         }
953                 }
954         }
955         _cycle_ports.reset ();
956         /* we are done */
957 }
958
959 PortEngine&
960 PortManager::port_engine()
961 {
962         assert (_backend);
963         return *_backend;
964 }
965
966 bool
967 PortManager::port_is_control_only (std::string const& name)
968 {
969         static regex_t compiled_pattern;
970         static string pattern;
971
972         if (pattern.empty()) {
973
974                 /* This is a list of regular expressions that match ports
975                  * related to physical MIDI devices that we do not want to
976                  * expose as normal physical ports.
977                  */
978
979                 const char * const control_only_ports[] = {
980                         X_(".*Ableton Push.*"),
981                         X_(".*FaderPort .*"),
982                         X_(".*FaderPort8 .*"),
983                         X_(".*FaderPort16 .*"),
984                         X_(".*FaderPort2 .*"),
985                         X_(".*US-2400 .*"),
986                         X_(".*Mackie .*"),
987                 };
988
989                 pattern = "(";
990                 for (size_t n = 0; n < sizeof (control_only_ports)/sizeof (control_only_ports[0]); ++n) {
991                         if (n > 0) {
992                                 pattern += '|';
993                         }
994                         pattern += control_only_ports[n];
995                 }
996                 pattern += ')';
997
998                 regcomp (&compiled_pattern, pattern.c_str(), REG_EXTENDED|REG_NOSUB);
999         }
1000
1001         return regexec (&compiled_pattern, name.c_str(), 0, 0, 0) == 0;
1002 }
1003
1004 PortManager::MidiPortInformation
1005 PortManager::midi_port_information (std::string const & name)
1006 {
1007         Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
1008
1009         fill_midi_port_info_locked ();
1010
1011         MidiPortInfo::iterator x = midi_port_info.find (name);
1012
1013         if (x != midi_port_info.end()) {
1014                 return x->second;
1015         }
1016
1017         return MidiPortInformation (string(), false, MidiPortFlags(0), false);
1018 }
1019
1020 void
1021 PortManager::get_known_midi_ports (vector<string>& copy)
1022 {
1023         Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
1024
1025         fill_midi_port_info_locked ();
1026
1027         for (MidiPortInfo::const_iterator x = midi_port_info.begin(); x != midi_port_info.end(); ++x) {
1028                 copy.push_back (x->first);
1029         }
1030 }
1031
1032 void
1033 PortManager::get_midi_selection_ports (vector<string>& copy)
1034 {
1035         Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
1036
1037         fill_midi_port_info_locked ();
1038
1039         for (MidiPortInfo::const_iterator x = midi_port_info.begin(); x != midi_port_info.end(); ++x) {
1040                 if (x->second.properties & MidiPortSelection) {
1041                         copy.push_back (x->first);
1042                 }
1043         }
1044 }
1045
1046 void
1047 PortManager::set_port_pretty_name (string const & port, string const & pretty)
1048 {
1049         bool emit = false;
1050         {
1051                 Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
1052
1053                 fill_midi_port_info_locked ();
1054
1055                 MidiPortInfo::iterator x = midi_port_info.find (port);
1056                 if (x == midi_port_info.end()) {
1057                         return;
1058                 }
1059                 x->second.pretty_name = pretty;
1060                 emit = true;
1061         }
1062
1063         /* push into back end */
1064
1065         PortEngine::PortHandle ph = _backend->get_port_by_name (port);
1066
1067         if (ph) {
1068                 _backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", pretty, string());
1069         }
1070
1071         if (emit) {
1072                 MidiPortInfoChanged (); /* EMIT SIGNAL*/
1073         }
1074 }
1075
1076 void
1077 PortManager::add_midi_port_flags (string const & port, MidiPortFlags flags)
1078 {
1079         bool emit = false;
1080
1081         {
1082                 Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
1083
1084                 fill_midi_port_info_locked ();
1085
1086                 MidiPortInfo::iterator x = midi_port_info.find (port);
1087                 if (x != midi_port_info.end()) {
1088                         if ((x->second.properties & flags) != flags) { // at least one missing
1089                                 x->second.properties = MidiPortFlags (x->second.properties | flags);
1090                                 emit = true;
1091                         }
1092                 }
1093         }
1094
1095         if (emit) {
1096                 if (flags & MidiPortSelection) {
1097                         MidiSelectionPortsChanged (); /* EMIT SIGNAL */
1098                 }
1099
1100                 if (flags != MidiPortSelection) {
1101                         MidiPortInfoChanged (); /* EMIT SIGNAL */
1102                 }
1103
1104                 save_midi_port_info ();
1105         }
1106 }
1107
1108 void
1109 PortManager::remove_midi_port_flags (string const & port, MidiPortFlags flags)
1110 {
1111         bool emit = false;
1112
1113         {
1114                 Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
1115
1116                 fill_midi_port_info_locked ();
1117
1118                 MidiPortInfo::iterator x = midi_port_info.find (port);
1119                 if (x != midi_port_info.end()) {
1120                         if (x->second.properties & flags) { // at least one is set
1121                                 x->second.properties = MidiPortFlags (x->second.properties & ~flags);
1122                                 emit = true;
1123                         }
1124                 }
1125         }
1126
1127         if (emit) {
1128                 if (flags & MidiPortSelection) {
1129                         MidiSelectionPortsChanged (); /* EMIT SIGNAL */
1130                 }
1131
1132                 if (flags != MidiPortSelection) {
1133                         MidiPortInfoChanged (); /* EMIT SIGNAL */
1134                 }
1135
1136                 save_midi_port_info ();
1137         }
1138 }
1139
1140 string
1141 PortManager::midi_port_info_file ()
1142 {
1143         return Glib::build_filename (user_config_directory(), X_("midi_port_info"));
1144 }
1145
1146 void
1147 PortManager::save_midi_port_info ()
1148 {
1149         string path = midi_port_info_file ();
1150
1151         XMLNode* root = new XMLNode (X_("MidiPortInfo"));
1152
1153         {
1154                 Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
1155
1156                 if (midi_port_info.empty()) {
1157                         delete root;
1158                         return;
1159                 }
1160
1161                 for (MidiPortInfo::iterator i = midi_port_info.begin(); i != midi_port_info.end(); ++i) {
1162                         XMLNode* node = new XMLNode (X_("port"));
1163                         node->set_property (X_("name"), i->first);
1164                         node->set_property (X_("canonical-name"), i->second.canonical_name);
1165                         node->set_property (X_("input"), i->second.input);
1166                         node->set_property (X_("properties"), i->second.properties);
1167                         root->add_child_nocopy (*node);
1168                 }
1169         }
1170
1171         XMLTree tree;
1172
1173         tree.set_root (root);
1174
1175         if (!tree.write (path)) {
1176                 error << string_compose (_("Could not save MIDI port info to %1"), path) << endmsg;
1177         }
1178 }
1179
1180 void
1181 PortManager::load_midi_port_info ()
1182 {
1183         string path = midi_port_info_file ();
1184         XMLTree tree;
1185
1186         if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
1187                 return;
1188         }
1189
1190         if (!tree.read (path)) {
1191                 error << string_compose (_("Cannot load MIDI port info from %1"), path) << endmsg;
1192                 return;
1193         }
1194
1195         midi_port_info.clear ();
1196
1197         for (XMLNodeConstIterator i = tree.root()->children().begin(); i != tree.root()->children().end(); ++i) {
1198                 string name;
1199                 string canonical;
1200                 bool  input;
1201                 MidiPortFlags properties;
1202
1203
1204                 if (!(*i)->get_property (X_("name"), name) ||
1205                     !(*i)->get_property (X_("canonical-name"), canonical) ||
1206                     !(*i)->get_property (X_("input"), input) ||
1207                     !(*i)->get_property (X_("properties"), properties)) {
1208                         continue;
1209                 }
1210
1211                 MidiPortInformation mpi (canonical, input, properties, false);
1212
1213                 midi_port_info.insert (make_pair (name, mpi));
1214         }
1215 }
1216
1217 void
1218 PortManager::fill_midi_port_info ()
1219 {
1220         {
1221                 Glib::Threads::Mutex::Lock lm (midi_port_info_mutex);
1222                 fill_midi_port_info_locked ();
1223         }
1224
1225         save_midi_port_info ();
1226 }
1227
1228 void
1229 PortManager::fill_midi_port_info_locked ()
1230 {
1231         /* MIDI info mutex MUST be held */
1232
1233         if (!midi_info_dirty || !_backend) {
1234                 return;
1235         }
1236
1237         std::vector<string> ports;
1238
1239         AudioEngine::instance()->get_ports (string(), DataType::MIDI, IsOutput, ports);
1240
1241         for (vector<string>::iterator p = ports.begin(); p != ports.end(); ++p) {
1242
1243                 if (port_is_mine (*p)) {
1244                         continue;
1245                 }
1246
1247                 if (midi_port_info.find (*p) == midi_port_info.end()) {
1248
1249                         MidiPortFlags flags (MidiPortFlags (0));
1250
1251                         if (port_is_control_only (*p)) {
1252                                 flags = MidiPortControl;
1253                         }
1254
1255                         MidiPortInformation mpi (string_compose ("%1%4%2%4%3", _backend->name(), _backend->device_name(), *p, MIDI_PORT_INFO_SEPARATOR_CHAR),
1256                                                  true,
1257                                                  flags,
1258                                                  true);
1259
1260 #ifdef LINUX
1261                         if ((*p.find (X_("Midi Through")) != string::npos || (*p).find (X_("Midi-Through")) != string::npos)) {
1262                                 mpi.properties = MidiPortFlags (mpi.properties | MidiPortVirtual);
1263                         }
1264 #endif
1265                         midi_port_info.insert (make_pair (*p, mpi));
1266                 }
1267         }
1268
1269         AudioEngine::instance()->get_ports (string(), DataType::MIDI, IsInput, ports);
1270
1271         for (vector<string>::iterator p = ports.begin(); p != ports.end(); ++p) {
1272
1273                 if (port_is_mine (*p)) {
1274                         continue;
1275                 }
1276
1277                 if (midi_port_info.find (*p) == midi_port_info.end()) {
1278
1279                         MidiPortFlags flags (MidiPortFlags (0));
1280
1281                         if (port_is_control_only (*p)) {
1282                                 flags = MidiPortControl;
1283                         }
1284
1285                         MidiPortInformation mpi (string_compose ("%1%4%2%4%3", _backend->name(), _backend->device_name(), *p, MIDI_PORT_INFO_SEPARATOR_CHAR),
1286                                                  false,
1287                                                  flags,
1288                                                  true);
1289
1290 #ifdef LINUX
1291                         if ((*p.find (X_("Midi Through")) != string::npos || (*p).find (X_("Midi-Through")) != string::npos)) {
1292                                 mpi.properties = MidiPortFlags (mpi.properties | MidiPortVirtual);
1293                         }
1294 #endif
1295                         midi_port_info.insert (make_pair (*p, mpi));
1296                 }
1297         }
1298
1299         /* now check with backend about which ports are present and pull
1300          * pretty-name if it exists
1301          */
1302
1303         for (MidiPortInfo::iterator x = midi_port_info.begin(); x != midi_port_info.end(); ++x) {
1304
1305                 vector<string> parts;
1306
1307                 /*PBD::*/split (x->second.canonical_name, parts, MIDI_PORT_INFO_SEPARATOR_CHAR);
1308                 assert (parts.size() == 3);
1309
1310                 if (parts[0] != _backend->name()) {
1311                         x->second.exists = false;
1312                         continue;
1313                 }
1314
1315                 if (parts[1] != _backend->device_name()) {
1316                         x->second.exists = false;
1317                         continue;
1318                 }
1319
1320                 PortEngine::PortHandle ph = _backend->get_port_by_name (parts[2]);
1321
1322                 if (!ph) {
1323                         /* port info saved from some condition where this port
1324                          * existed, but no longer does (i.e. device unplugged
1325                          * at present). We don't remove it from midi_port_info.
1326                          */
1327                         x->second.exists = false;
1328
1329                 } else {
1330                         x->second.exists = true;
1331                         /* check with backend for pre-existing pretty name */
1332
1333                         string value;
1334
1335                         value = AudioEngine::instance()->get_pretty_name_by_name (x->first);
1336
1337                         if (!value.empty()) {
1338                                 x->second.pretty_name = value;
1339                         } else {
1340                                 x->second.pretty_name = parts[2];
1341                         }
1342                 }
1343         }
1344
1345         midi_info_dirty = false;
1346 }