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