Make check for new Lilv optional.
[ardour.git] / libs / midi++2 / manager.cc
1 /*
2     Copyright (C) 1998-99 Paul Barton-Davis 
3     This program is free software; you can redistribute it and/or modify
4     it under the terms of the GNU General Public License as published by
5     the Free Software Foundation; either version 2 of the License, or
6     (at your option) any later version.
7
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     GNU General Public License for more details.
12
13     You should have received a copy of the GNU General Public License
14     along with this program; if not, write to the Free Software
15     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
17     $Id$
18 */
19
20 #include <fcntl.h>
21
22 #include <glib.h>
23
24 #include "pbd/error.h"
25
26 #include "midi++/types.h"
27 #include "midi++/manager.h"
28 #include "midi++/channel.h"
29 #include "midi++/port.h"
30 #include "midi++/jack_midi_port.h"
31 #include "midi++/mmc.h"
32
33 using namespace std;
34 using namespace MIDI;
35 using namespace PBD;
36
37 Manager *Manager::theManager = 0;
38
39 Manager::Manager (jack_client_t* jack)
40         : _ports (new PortList)
41 {
42         _mmc = new MachineControl (this, jack);
43         
44         _mtc_input_port = add_port (new MIDI::JackMIDIPort ("MTC in", Port::IsInput, jack));
45         _mtc_output_port = add_port (new MIDI::JackMIDIPort ("MTC out", Port::IsOutput, jack));
46         _midi_input_port = add_port (new MIDI::JackMIDIPort ("MIDI control in", Port::IsInput, jack));
47         _midi_output_port = add_port (new MIDI::JackMIDIPort ("MIDI control out", Port::IsOutput, jack));
48         _midi_clock_input_port = add_port (new MIDI::JackMIDIPort ("MIDI clock in", Port::IsInput, jack));
49         _midi_clock_output_port = add_port (new MIDI::JackMIDIPort ("MIDI clock out", Port::IsOutput, jack));
50 }
51
52 Manager::~Manager ()
53 {
54         delete _mmc;
55         
56         /* This will delete our MTC etc. ports */
57
58         boost::shared_ptr<PortList> pr = _ports.reader ();
59         for (PortList::iterator p = pr->begin(); p != pr->end(); ++p) {
60                 delete *p;
61         }
62
63         if (theManager == this) {
64                 theManager = 0;
65         }
66 }
67
68 Port *
69 Manager::add_port (Port* p)
70 {
71         {
72                 RCUWriter<PortList> writer (_ports);
73                 boost::shared_ptr<PortList> pw = writer.get_copy ();
74                 pw->push_back (p);
75         }
76
77         PortsChanged (); /* EMIT SIGNAL */
78
79         return p;
80 }
81
82 void
83 Manager::remove_port (Port* p)
84 {
85         {
86                 RCUWriter<PortList> writer (_ports);
87                 boost::shared_ptr<PortList> pw = writer.get_copy ();
88                 pw->remove (p);
89         }
90
91         PortsChanged (); /* EMIT SIGNAL */
92 }
93
94 void
95 Manager::cycle_start (pframes_t nframes)
96 {
97         boost::shared_ptr<PortList> pr = _ports.reader ();
98         
99         for (PortList::iterator p = pr->begin(); p != pr->end(); ++p) {
100                 (*p)->cycle_start (nframes);
101         }
102 }
103
104 void
105 Manager::cycle_end()
106 {
107         boost::shared_ptr<PortList> pr = _ports.reader ();
108         
109         for (PortList::iterator p = pr->begin(); p != pr->end(); ++p) {
110                 (*p)->cycle_end ();
111         }
112 }
113
114 /** Re-register ports that disappear on JACK shutdown */
115 void
116 Manager::reestablish (jack_client_t* jack)
117 {
118         boost::shared_ptr<PortList> pr = _ports.reader ();
119
120         for (PortList::const_iterator p = pr->begin(); p != pr->end(); ++p) {
121                 JackMIDIPort* pp = dynamic_cast<JackMIDIPort*> (*p);
122                 if (pp) {
123                         pp->reestablish (jack);
124                 }
125         }
126 }
127
128 /** Re-connect ports after a reestablish () */
129 void
130 Manager::reconnect ()
131 {
132         boost::shared_ptr<PortList> pr = _ports.reader ();
133
134         for (PortList::const_iterator p = pr->begin(); p != pr->end(); ++p) {
135                 JackMIDIPort* pp = dynamic_cast<JackMIDIPort*> (*p);
136                 if (pp) {
137                         pp->reconnect ();
138                 }
139         }
140 }
141
142 Port*
143 Manager::port (string const & n)
144 {
145         boost::shared_ptr<PortList> pr = _ports.reader ();
146         
147         PortList::const_iterator p = pr->begin();
148         while (p != pr->end() && (*p)->name() != n) {
149                 ++p;
150         }
151
152         if (p == pr->end()) {
153                 return 0;
154         }
155
156         return *p;
157 }
158
159 void
160 Manager::create (jack_client_t* jack)
161 {
162         assert (theManager == 0);
163         theManager = new Manager (jack);
164 }
165
166 void
167 Manager::set_port_states (list<XMLNode*> s)
168 {
169         boost::shared_ptr<PortList> pr = _ports.reader ();
170         
171         for (list<XMLNode*>::iterator i = s.begin(); i != s.end(); ++i) {
172                 for (PortList::const_iterator j = pr->begin(); j != pr->end(); ++j) {
173                         (*j)->set_state (**i);
174                 }
175         }
176 }
177
178 void
179 Manager::destroy ()
180 {
181         delete theManager;
182         theManager = 0;
183 }