NOOP, remove trailing tabs/whitespace.
[ardour.git] / libs / midi++2 / port.cc
1 /*
2     Copyright (C) 1998 Paul Barton-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     $Id: port.cc 11871 2012-04-10 16:27:01Z paul $
19 */
20 #include <iostream>
21 #include <cstdio>
22 #include <fcntl.h>
23 #include <errno.h>
24
25 #include "pbd/xml++.h"
26 #include "pbd/error.h"
27 #include "pbd/failed_constructor.h"
28 #include "pbd/convert.h"
29 #include "pbd/strsplit.h"
30 #include "pbd/stacktrace.h"
31
32 #include "midi++/types.h"
33 #include "midi++/port.h"
34 #include "midi++/channel.h"
35
36 using namespace MIDI;
37 using namespace std;
38 using namespace PBD;
39
40 string Port::state_node_name = "MIDI-port";
41
42 Port::Port (string const & name, Flags flags)
43         : _flags (flags)
44         , _centrally_parsed (true)
45 {
46         init (name, flags);
47 }
48
49 Port::Port (const XMLNode& node)
50         : _centrally_parsed (true)
51 {
52         Descriptor desc (node);
53
54         init (desc.tag, desc.flags);
55
56         /* derived class must call ::set_state() */
57 }
58
59 void
60 Port::init (string const & name, Flags flags)
61 {
62         _ok = false;  /* derived class must set to true if constructor
63                          succeeds.
64                       */
65
66         _parser = 0;
67
68         _tagname = name;
69         _flags = flags;
70
71         _parser = new Parser ();
72
73         for (int i = 0; i < 16; i++) {
74                 _channel[i] = new Channel (i, *this);
75                 _channel[i]->connect_signals ();
76         }
77 }
78
79 Port::~Port ()
80 {
81         for (int i = 0; i < 16; i++) {
82                 delete _channel[i];
83         }
84
85         delete _parser;
86 }
87
88 /** Send a clock tick message.
89  * \return true on success.
90  */
91 bool
92 Port::clock (timestamp_t timestamp)
93 {
94         static byte clockmsg = 0xf8;
95
96         if (sends_output()) {
97                 return midimsg (&clockmsg, 1, timestamp);
98         }
99
100         return false;
101 }
102
103 std::ostream & MIDI::operator << ( std::ostream & os, const MIDI::Port & port )
104 {
105         using namespace std;
106         os << "MIDI::Port { ";
107         os << "name: " << port.name();
108         os << "; ";
109         os << "ok: " << port.ok();
110         os << "; ";
111         os << " }";
112         return os;
113 }
114
115 Port::Descriptor::Descriptor (const XMLNode& node)
116 {
117         const XMLProperty *prop;
118         bool have_tag = false;
119         bool have_mode = false;
120
121         if ((prop = node.property ("tag")) != 0) {
122                 tag = prop->value();
123                 have_tag = true;
124         }
125
126         if ((prop = node.property ("mode")) != 0) {
127
128                 if (strings_equal_ignore_case (prop->value(), "output") || strings_equal_ignore_case (prop->value(), "out")) {
129                         flags = IsOutput;
130                 } else if (strings_equal_ignore_case (prop->value(), "input") || strings_equal_ignore_case (prop->value(), "in")) {
131                         flags = IsInput;
132                 }
133
134                 have_mode = true;
135         }
136
137         if (!have_tag || !have_mode) {
138                 throw failed_constructor();
139         }
140 }
141
142 XMLNode&
143 Port::get_state () const
144 {
145         XMLNode* root = new XMLNode (state_node_name);
146         root->add_property ("tag", _tagname);
147
148         if (_flags == IsInput) {
149                 root->add_property ("mode", "input");
150         } else {
151                 root->add_property ("mode", "output");
152         }
153
154 #if 0
155         byte device_inquiry[6];
156
157         device_inquiry[0] = 0xf0;
158         device_inquiry[0] = 0x7e;
159         device_inquiry[0] = 0x7f;
160         device_inquiry[0] = 0x06;
161         device_inquiry[0] = 0x02;
162         device_inquiry[0] = 0xf7;
163
164         write (device_inquiry, sizeof (device_inquiry), 0);
165 #endif
166
167         return *root;
168 }
169
170 void
171 Port::set_state (const XMLNode& node)
172 {
173         const XMLProperty* prop;
174
175         if ((prop = node.property ("tag")) == 0 || prop->value() != _tagname) {
176                 return;
177         }
178 }
179
180 bool
181 Port::centrally_parsed() const
182 {
183         return _centrally_parsed;
184 }