add color property to MIDISceneChange
[ardour.git] / libs / ardour / midi_scene_change.cc
1 /*
2     Copyright (C) 2014 Paul 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 */
19
20 #include "pbd/error.h"
21 #include "pbd/compose.h"
22
23 #include "ardour/midi_port.h"
24 #include "ardour/midi_scene_change.h"
25
26 #include "i18n.h"
27
28 using namespace PBD;
29 using namespace ARDOUR;
30
31 MIDISceneChange::MIDISceneChange (int c, int b, int p)
32         : _bank (b)
33         , _program (p)
34         , _channel (c & 0xf)
35         , _color (0x00000000) /* note: zero alpha means invisible, which acts as out-of-bound signal */
36 {
37         if (_bank > 16384) {
38                 _bank = -1;
39         }
40
41         if (_program > 128) {
42                 _program = -1;
43         }
44 }
45
46 MIDISceneChange::MIDISceneChange (const XMLNode& node, int version)
47         : _bank (-1)
48         , _program (-1)
49         , _channel (-1)
50 {
51         set_state (node, version);
52 }
53
54 MIDISceneChange::~MIDISceneChange ()
55 {
56 }
57
58 size_t
59 MIDISceneChange::get_bank_msb_message (uint8_t* buf, size_t size) const
60 {
61         if (size < 3 || _bank < 0) {
62                 return 0;
63         }
64
65         buf[0] = 0xB0 | (_channel & 0xf);
66         buf[1] = 0x0;
67         buf[2] = (_bank >> 7) & 0x7f;
68
69         return 3;
70 }
71
72 size_t
73 MIDISceneChange::get_bank_lsb_message (uint8_t* buf, size_t size) const
74 {
75         if (size < 3 || _bank < 0) {
76                 return 0;
77         }
78
79         buf[0] = 0xB0 | (_channel & 0xf);
80         buf[1] = 0x20;
81         buf[2] = _bank & 0x7f;  
82
83         return 3;
84 }
85
86 size_t
87 MIDISceneChange::get_program_message (uint8_t* buf, size_t size) const
88 {
89         if (size < 2 || _program < 0) {
90                 return 0;
91         }
92
93         buf[0] = 0xC0 | (_channel & 0xf);
94         buf[1] = _program & 0x7f;
95
96         return 2;
97 }
98
99 XMLNode&
100 MIDISceneChange::get_state ()
101 {
102         char buf[32];
103         XMLNode* node = new XMLNode (SceneChange::xml_node_name);
104
105         node->add_property (X_("type"), X_("MIDI"));
106         snprintf (buf, sizeof (buf), "%d", (int) _program);
107         node->add_property (X_("id"), id().to_s());
108         snprintf (buf, sizeof (buf), "%d", (int) _program);
109         node->add_property (X_("program"), buf);
110         snprintf (buf, sizeof (buf), "%d", (int) _bank);
111         node->add_property (X_("bank"), buf);
112         snprintf (buf, sizeof (buf), "%d", (int) _channel);
113         node->add_property (X_("channel"), buf);
114
115         return *node;
116 }
117
118 int
119 MIDISceneChange::set_state (const XMLNode& node, int /* version-ignored */)
120 {
121         if (!set_id (node)) {
122                 return -1;
123         }
124
125         const XMLProperty* prop;
126
127         if ((prop = node.property (X_("program"))) == 0) {
128                 return -1;
129         }
130         _program = atoi (prop->value());
131
132         if ((prop = node.property (X_("bank"))) == 0) {
133                 return -1;
134         }
135         _bank = atoi (prop->value());
136
137         if ((prop = node.property (X_("channel"))) == 0) {
138                 return -1;
139         }
140         _channel = atoi (prop->value());
141
142         return 0;
143 }
144
145 bool
146 MIDISceneChange::operator==(const MIDISceneChange& other) const
147 {
148         return _program == other._program &&
149                 _bank == other._bank &&
150                 _channel == other._channel;
151 }
152
153 void
154 MIDISceneChange::set_color (uint32_t c) 
155 {
156         _color = c;
157         ColorChanged (); /* EMIT SIGNAL */
158 }
159
160 uint32_t
161 MIDISceneChange::color() const
162 {
163         return _color;
164 }