03e418e4b24f48fbd3d77b9375d1c7c909b16ca7
[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++/mmc.h"
31
32 using namespace std;
33 using namespace MIDI;
34 using namespace PBD;
35
36 Manager *Manager::theManager = 0;
37
38 Manager::Manager (jack_client_t* jack)
39         : _ports (new PortList)
40 {
41         _mmc = new MachineControl (this, jack);
42         
43         _mtc_input_port = add_port (new MIDI::Port ("MTC in", Port::IsInput, jack));
44         _mtc_output_port = add_port (new MIDI::Port ("MTC out", Port::IsOutput, jack));
45         _midi_input_port = add_port (new MIDI::Port ("MIDI control in", Port::IsInput, jack));
46         _midi_output_port = add_port (new MIDI::Port ("MIDI control out", Port::IsOutput, jack));
47         _midi_clock_input_port = add_port (new MIDI::Port ("MIDI clock in", Port::IsInput, jack));
48         _midi_clock_output_port = add_port (new MIDI::Port ("MIDI clock out", Port::IsOutput, jack));
49 }
50
51 Manager::~Manager ()
52 {
53         delete _mmc;
54         
55         /* This will delete our MTC etc. ports */
56
57         boost::shared_ptr<PortList> pr = _ports.reader ();
58         for (PortList::iterator p = pr->begin(); p != pr->end(); ++p) {
59                 delete *p;
60         }
61
62         if (theManager == this) {
63                 theManager = 0;
64         }
65 }
66
67 Port *
68 Manager::add_port (Port* p)
69 {
70         {
71                 RCUWriter<PortList> writer (_ports);
72                 boost::shared_ptr<PortList> pw = writer.get_copy ();
73                 pw->push_back (p);
74         }
75
76         PortsChanged (); /* EMIT SIGNAL */
77
78         return p;
79 }
80
81 void
82 Manager::remove_port (Port* p)
83 {
84         {
85                 RCUWriter<PortList> writer (_ports);
86                 boost::shared_ptr<PortList> pw = writer.get_copy ();
87                 pw->remove (p);
88         }
89
90         PortsChanged (); /* EMIT SIGNAL */
91 }
92
93 void
94 Manager::cycle_start (pframes_t nframes)
95 {
96         boost::shared_ptr<PortList> pr = _ports.reader ();
97         
98         for (PortList::iterator p = pr->begin(); p != pr->end(); ++p) {
99                 (*p)->cycle_start (nframes);
100         }
101 }
102
103 void
104 Manager::cycle_end()
105 {
106         boost::shared_ptr<PortList> pr = _ports.reader ();
107         
108         for (PortList::iterator p = pr->begin(); p != pr->end(); ++p) {
109                 (*p)->cycle_end ();
110         }
111 }
112
113 /** Re-register ports that disappear on JACK shutdown */
114 void
115 Manager::reestablish (jack_client_t* jack)
116 {
117         boost::shared_ptr<PortList> pr = _ports.reader ();
118
119         for (PortList::const_iterator p = pr->begin(); p != pr->end(); ++p) {
120                 (*p)->reestablish (jack);
121         }
122 }
123
124 /** Re-connect ports after a reestablish () */
125 void
126 Manager::reconnect ()
127 {
128         boost::shared_ptr<PortList> pr = _ports.reader ();
129
130         for (PortList::const_iterator p = pr->begin(); p != pr->end(); ++p) {
131                 (*p)->reconnect ();
132         }
133 }
134
135 Port*
136 Manager::port (string const & n)
137 {
138         boost::shared_ptr<PortList> pr = _ports.reader ();
139         
140         PortList::const_iterator p = pr->begin();
141         while (p != pr->end() && (*p)->name() != n) {
142                 ++p;
143         }
144
145         if (p == pr->end()) {
146                 return 0;
147         }
148
149         return *p;
150 }
151
152 void
153 Manager::create (jack_client_t* jack)
154 {
155         assert (theManager == 0);
156         theManager = new Manager (jack);
157 }
158
159 void
160 Manager::set_port_states (list<XMLNode*> s)
161 {
162         boost::shared_ptr<PortList> pr = _ports.reader ();
163         
164         for (list<XMLNode*>::iterator i = s.begin(); i != s.end(); ++i) {
165                 for (PortList::const_iterator j = pr->begin(); j != pr->end(); ++j) {
166                         (*j)->set_state (**i);
167                 }
168         }
169 }