various fixes to MidiRegionView selection handling, key handling, drawing of ghost...
[ardour2.git] / libs / evoral / evoral / PatchChange.hpp
blob576a1d2e983d61fc706420636d3a59774e20a3e6
1 /*
2 Copyright (C) 2010 Paul Davis
3 Author: Carl Hetherington <cth@carlh.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #ifndef EVORAL_PATCH_CHANGE_HPP
21 #define EVORAL_PATCH_CHANGE_HPP
23 #include "evoral/Event.hpp"
24 #include "evoral/MIDIEvent.hpp"
26 namespace Evoral {
28 /** Event representing a `patch change', composed of a LSB and MSB
29 * bank select and then a program change.
31 template<typename Time>
32 class PatchChange
34 public:
35 /** @param t Time.
36 * @param c Channel.
37 * @param p Program change number (counted from 0).
38 * @param b Bank number (counted from 0, 14-bit).
40 PatchChange (Time t, uint8_t c, uint8_t p, int b)
41 : _bank_change_msb (0, t, 3, 0, true)
42 , _bank_change_lsb (0, t, 3, 0, true)
43 , _program_change (0, t, 2, 0, true)
45 _bank_change_msb.buffer()[0] = MIDI_CMD_CONTROL | c;
46 _bank_change_msb.buffer()[1] = MIDI_CTL_MSB_BANK;
47 _bank_change_msb.buffer()[2] = (b >> 7) & 0x7f;
49 _bank_change_lsb.buffer()[0] = MIDI_CMD_CONTROL | c;
50 _bank_change_lsb.buffer()[1] = MIDI_CTL_LSB_BANK;
51 _bank_change_lsb.buffer()[2] = b & 0x7f;
53 _program_change.buffer()[0] = MIDI_CMD_PGM_CHANGE | c;
54 _program_change.buffer()[1] = p;
57 PatchChange (const PatchChange & other)
58 : _bank_change_msb (other._bank_change_msb, true)
59 , _bank_change_lsb (other._bank_change_lsb, true)
60 , _program_change (other._program_change, true)
62 set_id (other.id ());
65 event_id_t id () const {
66 return _program_change.id ();
69 void set_id (event_id_t id) {
70 _bank_change_msb.set_id (id);
71 _bank_change_lsb.set_id (id);
72 _program_change.set_id (id);
75 Time time () const {
76 return _program_change.time ();
79 void set_time (Time t) {
80 _bank_change_msb.set_time (t);
81 _bank_change_lsb.set_time (t);
82 _program_change.set_time (t);
85 void set_channel (uint8_t c) {
86 _bank_change_msb.buffer()[0] &= 0xf0;
87 _bank_change_msb.buffer()[0] |= c;
88 _bank_change_lsb.buffer()[0] &= 0xf0;
89 _bank_change_lsb.buffer()[0] |= c;
90 _program_change.buffer()[0] &= 0xf0;
91 _program_change.buffer()[0] |= c;
94 uint8_t program () const {
95 return _program_change.buffer()[1];
98 void set_program (uint8_t p) {
99 _program_change.buffer()[1] = p;
102 int bank () const {
103 return (bank_msb() << 7) | bank_lsb();
106 void set_bank (int b) {
107 _bank_change_msb.buffer()[2] = (b >> 7) & 0x7f;
108 _bank_change_lsb.buffer()[2] = b & 0x7f;
111 uint8_t bank_msb () const {
112 return _bank_change_msb.buffer()[2];
115 uint8_t bank_lsb () const {
116 return _bank_change_lsb.buffer()[2];
119 uint8_t channel () const { return _program_change.buffer()[0] & 0xf; }
121 inline bool operator< (const PatchChange<Time>& o) const {
122 if (time() != o.time()) {
123 return time() < o.time();
126 if (bank != o.bank()) {
127 return bank() < o.bank();
130 return (program() < o.program());
133 inline bool operator== (const PatchChange<Time>& o) const {
134 return (time() == o.time() && program() == o.program() && bank() == o.bank());
137 /** The PatchChange is made up of messages() MIDI messages; this method returns them by index.
138 * @param i index of message to return.
140 MIDIEvent<Time> const & message (int i) const {
141 switch (i) {
142 case 0:
143 return _bank_change_msb;
144 case 1:
145 return _bank_change_lsb;
146 case 2:
147 return _program_change;
148 default:
149 assert (false);
153 /** @return Number of MIDI messages that make up this change */
154 int messages () const {
155 return 3;
158 private:
159 MIDIEvent<Time> _bank_change_msb;
160 MIDIEvent<Time> _bank_change_lsb;
161 MIDIEvent<Time> _program_change;
166 #endif