2 Copyright (C) 1998 Paul Barton-Davis
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.
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.
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.
18 $Id: port.cc 11871 2012-04-10 16:27:01Z paul $
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"
32 #include "midi++/types.h"
33 #include "midi++/port.h"
34 #include "midi++/channel.h"
40 string Port::state_node_name = "MIDI-port";
42 Port::Port (string const & name, Flags flags)
44 , _centrally_parsed (true)
49 Port::Port (const XMLNode& node)
50 : _centrally_parsed (true)
52 Descriptor desc (node);
54 init (desc.tag, desc.flags);
56 /* derived class must call ::set_state() */
60 Port::init (string const & name, Flags flags)
62 _ok = false; /* derived class must set to true if constructor
71 _parser = new Parser ();
73 for (int i = 0; i < 16; i++) {
74 _channel[i] = new Channel (i, *this);
75 _channel[i]->connect_signals ();
81 for (int i = 0; i < 16; i++) {
88 /** Send a clock tick message.
89 * \return true on success.
92 Port::clock (timestamp_t timestamp)
94 static byte clockmsg = 0xf8;
97 return midimsg (&clockmsg, 1, timestamp);
103 std::ostream & MIDI::operator << ( std::ostream & os, const MIDI::Port & port )
106 os << "MIDI::Port { ";
107 os << "name: " << port.name();
109 os << "ok: " << port.ok();
115 Port::Descriptor::Descriptor (const XMLNode& node)
117 const XMLProperty *prop;
118 bool have_tag = false;
119 bool have_mode = false;
121 if ((prop = node.property ("tag")) != 0) {
126 if ((prop = node.property ("mode")) != 0) {
128 if (strings_equal_ignore_case (prop->value(), "output") || strings_equal_ignore_case (prop->value(), "out")) {
130 } else if (strings_equal_ignore_case (prop->value(), "input") || strings_equal_ignore_case (prop->value(), "in")) {
137 if (!have_tag || !have_mode) {
138 throw failed_constructor();
143 Port::get_state () const
145 XMLNode* root = new XMLNode (state_node_name);
146 root->add_property ("tag", _tagname);
148 if (_flags == IsInput) {
149 root->add_property ("mode", "input");
151 root->add_property ("mode", "output");
155 byte device_inquiry[6];
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;
164 write (device_inquiry, sizeof (device_inquiry), 0);
171 Port::set_state (const XMLNode& node)
173 const XMLProperty* prop;
175 if ((prop = node.property ("tag")) == 0 || prop->value() != _tagname) {
181 Port::centrally_parsed() const
183 return _centrally_parsed;