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++) {
86 /** Send a clock tick message.
87 * \return true on success.
90 Port::clock (timestamp_t timestamp)
92 static byte clockmsg = 0xf8;
95 return midimsg (&clockmsg, 1, timestamp);
101 std::ostream & MIDI::operator << ( std::ostream & os, const MIDI::Port & port )
104 os << "MIDI::Port { ";
105 os << "name: " << port.name();
107 os << "ok: " << port.ok();
113 Port::Descriptor::Descriptor (const XMLNode& node)
115 const XMLProperty *prop;
116 bool have_tag = false;
117 bool have_mode = false;
119 if ((prop = node.property ("tag")) != 0) {
124 if ((prop = node.property ("mode")) != 0) {
126 if (strings_equal_ignore_case (prop->value(), "output") || strings_equal_ignore_case (prop->value(), "out")) {
128 } else if (strings_equal_ignore_case (prop->value(), "input") || strings_equal_ignore_case (prop->value(), "in")) {
135 if (!have_tag || !have_mode) {
136 throw failed_constructor();
141 Port::get_state () const
143 XMLNode* root = new XMLNode (state_node_name);
144 root->add_property ("tag", _tagname);
146 if (_flags == IsInput) {
147 root->add_property ("mode", "input");
149 root->add_property ("mode", "output");
153 byte device_inquiry[6];
155 device_inquiry[0] = 0xf0;
156 device_inquiry[0] = 0x7e;
157 device_inquiry[0] = 0x7f;
158 device_inquiry[0] = 0x06;
159 device_inquiry[0] = 0x02;
160 device_inquiry[0] = 0xf7;
162 write (device_inquiry, sizeof (device_inquiry), 0);
169 Port::set_state (const XMLNode& node)
171 const XMLProperty* prop;
173 if ((prop = node.property ("tag")) == 0 || prop->value() != _tagname) {
179 Port::centrally_parsed() const
181 return _centrally_parsed;