move ownership of an RT MIDI buffer from DiskIO to MidiPlaylist
[ardour.git] / libs / ardour / midi_scene_change.cc
1 /*
2  * Copyright (C) 2014-2016 Paul Davis <paul@linuxaudiosystems.com>
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 along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include "pbd/error.h"
20 #include "pbd/compose.h"
21 #include "pbd/types_convert.h"
22
23 #include "ardour/midi_port.h"
24 #include "ardour/midi_scene_change.h"
25
26 #include "pbd/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 {
36         if (_bank > 16384) {
37                 _bank = -1;
38         }
39
40         if (_program > 128) {
41                 _program = -1;
42         }
43 }
44
45 MIDISceneChange::MIDISceneChange (const XMLNode& node, int version)
46         : _bank (-1)
47         , _program (-1)
48         , _channel (-1)
49 {
50         set_state (node, version);
51 }
52
53 MIDISceneChange::~MIDISceneChange ()
54 {
55 }
56
57 size_t
58 MIDISceneChange::get_bank_msb_message (uint8_t* buf, size_t size) const
59 {
60         if (size < 3 || _bank < 0) {
61                 return 0;
62         }
63
64         buf[0] = 0xB0 | (_channel & 0xf);
65         buf[1] = 0x0;
66         buf[2] = (_bank >> 7) & 0x7f;
67
68         return 3;
69 }
70
71 size_t
72 MIDISceneChange::get_bank_lsb_message (uint8_t* buf, size_t size) const
73 {
74         if (size < 3 || _bank < 0) {
75                 return 0;
76         }
77
78         buf[0] = 0xB0 | (_channel & 0xf);
79         buf[1] = 0x20;
80         buf[2] = _bank & 0x7f;
81
82         return 3;
83 }
84
85 size_t
86 MIDISceneChange::get_program_message (uint8_t* buf, size_t size) const
87 {
88         if (size < 2 || _program < 0) {
89                 return 0;
90         }
91
92         buf[0] = 0xC0 | (_channel & 0xf);
93         buf[1] = _program & 0x7f;
94
95         return 2;
96 }
97
98 XMLNode&
99 MIDISceneChange::get_state ()
100 {
101         XMLNode* node = new XMLNode (SceneChange::xml_node_name);
102
103         node->set_property (X_("type"), X_("MIDI"));
104         node->set_property (X_("id"), id());
105         node->set_property (X_("program"), _program);
106         node->set_property (X_("bank"), _bank);
107         node->set_property (X_("channel"), _channel);
108         node->set_property (X_("color"), _color);
109
110         return *node;
111 }
112
113 int
114 MIDISceneChange::set_state (const XMLNode& node, int /* version-ignored */)
115 {
116         if (!set_id (node)) {
117                 return -1;
118         }
119
120         if (!node.get_property (X_("program"), _program) || !node.get_property (X_("bank"), _bank) ||
121             !node.get_property (X_("channel"), _channel)) {
122                 return -1;
123         }
124
125         if (!node.get_property (X_("color"), _color)) {
126                 _color = out_of_bound_color;
127         }
128
129         return 0;
130 }
131
132 bool
133 MIDISceneChange::operator==(const MIDISceneChange& other) const
134 {
135         return _program == other._program &&
136                 _bank == other._bank &&
137                 _channel == other._channel;
138 }
139
140 void
141 MIDISceneChange::set_channel (int channel)
142 {
143         _channel = channel;
144 }
145
146 void
147 MIDISceneChange::set_program (int program)
148 {
149         _program = program;
150 }
151
152 void
153 MIDISceneChange::set_bank (int bank)
154 {
155         _bank = bank;
156 }
157
158