ardour
PatchChange.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 Paul Davis
3  Author: Carl Hetherington <cth@carlh.net>
4 
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.
9 
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.
14 
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.
18 */
19 
20 #ifndef EVORAL_PATCH_CHANGE_HPP
21 #define EVORAL_PATCH_CHANGE_HPP
22 
23 #include "evoral/visibility.h"
24 #include "evoral/Event.hpp"
25 #include "evoral/MIDIEvent.hpp"
26 
27 namespace Evoral {
28 
32 template<typename Time>
33 class /*LIBEVORAL_API*/ PatchChange
34 {
35 public:
41  PatchChange (Time t, uint8_t c, uint8_t p, int b)
42  : _bank_change_msb (0, t, 3, 0, true)
43  , _bank_change_lsb (0, t, 3, 0, true)
44  , _program_change (0, t, 2, 0, true)
45  {
46  _bank_change_msb.buffer()[0] = MIDI_CMD_CONTROL | c;
47  _bank_change_msb.buffer()[1] = MIDI_CTL_MSB_BANK;
48  _bank_change_msb.buffer()[2] = (b >> 7) & 0x7f;
49 
50  _bank_change_lsb.buffer()[0] = MIDI_CMD_CONTROL | c;
51  _bank_change_lsb.buffer()[1] = MIDI_CTL_LSB_BANK;
52  _bank_change_lsb.buffer()[2] = b & 0x7f;
53 
54  _program_change.buffer()[0] = MIDI_CMD_PGM_CHANGE | c;
55  _program_change.buffer()[1] = p;
56  }
57 
58  PatchChange (const PatchChange & other)
59  : _bank_change_msb (other._bank_change_msb, true)
60  , _bank_change_lsb (other._bank_change_lsb, true)
61  , _program_change (other._program_change, true)
62  {
63  set_id (other.id ());
64  }
65 
66  event_id_t id () const {
67  return _program_change.id ();
68  }
69 
70  void set_id (event_id_t id) {
71  _bank_change_msb.set_id (id);
72  _bank_change_lsb.set_id (id);
73  _program_change.set_id (id);
74  }
75 
76  Time time () const {
77  return _program_change.time ();
78  }
79 
80  void set_time (Time t) {
81  _bank_change_msb.set_time (t);
82  _bank_change_lsb.set_time (t);
83  _program_change.set_time (t);
84  }
85 
86  void set_channel (uint8_t c) {
87  _bank_change_msb.buffer()[0] &= 0xf0;
88  _bank_change_msb.buffer()[0] |= c;
89  _bank_change_lsb.buffer()[0] &= 0xf0;
90  _bank_change_lsb.buffer()[0] |= c;
91  _program_change.buffer()[0] &= 0xf0;
92  _program_change.buffer()[0] |= c;
93  }
94 
95  uint8_t program () const {
96  return _program_change.buffer()[1];
97  }
98 
99  void set_program (uint8_t p) {
100  _program_change.buffer()[1] = p;
101  }
102 
103  int bank () const {
104  return (bank_msb() << 7) | bank_lsb();
105  }
106 
107  void set_bank (int b) {
108  _bank_change_msb.buffer()[2] = (b >> 7) & 0x7f;
109  _bank_change_lsb.buffer()[2] = b & 0x7f;
110  }
111 
112  uint8_t bank_msb () const {
113  return _bank_change_msb.buffer()[2];
114  }
115 
116  uint8_t bank_lsb () const {
117  return _bank_change_lsb.buffer()[2];
118  }
119 
120  uint8_t channel () const { return _program_change.buffer()[0] & 0xf; }
121 
122  inline bool operator< (const PatchChange<Time>& o) const {
123  if (time() != o.time()) {
124  return time() < o.time();
125  }
126 
127  if (bank() != o.bank()) {
128  return bank() < o.bank();
129  }
130 
131  return (program() < o.program());
132  }
133 
134  inline bool operator== (const PatchChange<Time>& o) const {
135  return (time() == o.time() && program() == o.program() && bank() == o.bank());
136  }
137 
141  MIDIEvent<Time> const & message (int i) const {
142  switch (i) {
143  case 0:
144  return _bank_change_msb;
145  case 1:
146  return _bank_change_lsb;
147  case 2:
148  return _program_change;
149  default:
150  abort(); /*NOTREACHED*/
151  return _program_change;
152  }
153  }
154 
156  int messages () const {
157  return 3;
158  }
159 
160 private:
164 };
165 
166 }
167 
168 template<typename Time>
169 /*LIBEVORAL_API*/ std::ostream& operator<< (std::ostream& o, const Evoral::PatchChange<Time>& p) {
170  o << "Patch Change " << p.id() << " @ " << p.time() << " bank " << (int) p.bank() << " program " << (int) p.program();
171  return o;
172 }
173 
174 #endif
MIDIEvent< Time > _program_change
uint8_t bank_lsb() const
#define MIDI_CTL_MSB_BANK
Definition: midi_events.h:33
int messages() const
bool operator==(const PatchChange< Time > &o) const
int32_t event_id_t
Definition: types.hpp:40
MIDIEvent< Time > const & message(int i) const
#define MIDI_CTL_LSB_BANK
Definition: midi_events.h:49
#define MIDI_CMD_PGM_CHANGE
Definition: midi_events.h:111
uint8_t program() const
Definition: PatchChange.hpp:95
uint8_t channel() const
MIDIEvent< Time > _bank_change_lsb
#define MIDI_CMD_CONTROL
Definition: midi_events.h:110
uint8_t bank_msb() const
void set_id(event_id_t id)
Definition: PatchChange.hpp:70
void set_bank(int b)
PatchChange(const PatchChange &other)
Definition: PatchChange.hpp:58
void set_time(Time t)
Definition: PatchChange.hpp:80
event_id_t id() const
Definition: PatchChange.hpp:66
void set_program(uint8_t p)
Definition: PatchChange.hpp:99
Time time() const
Definition: PatchChange.hpp:76
void set_channel(uint8_t c)
Definition: PatchChange.hpp:86
MIDIEvent< Time > _bank_change_msb
PatchChange(Time t, uint8_t c, uint8_t p, int b)
Definition: PatchChange.hpp:41