sequencer
channel_voice.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <sequencer/assert.hpp>
7 
8 #include <cstdint>
9 #include <tuple>
10 
12 {
13  constexpr message_t< 3 > note_on( std::uint8_t channel, std::uint8_t note,
14  std::uint8_t velocity ) noexcept
15  {
16  SEQUENCER_ASSERT( channel < 16 );
17  SEQUENCER_ASSERT( note < 128 );
18  SEQUENCER_ASSERT( velocity < 128 );
19 
20  return {status_byte_for( byte::note_on, channel ), std::byte{note}, std::byte{velocity}};
21  }
22 
23  constexpr message_t< 3 > note_off( std::uint8_t channel, std::uint8_t note,
24  std::uint8_t velocity ) noexcept
25  {
26  SEQUENCER_ASSERT( channel < 16 );
27  SEQUENCER_ASSERT( note < 128 );
28  SEQUENCER_ASSERT( velocity < 128 );
29 
30  return {status_byte_for( byte::note_off, channel ), std::byte{note}, std::byte{velocity}};
31  }
32 
33  constexpr message_t< 3 > polymorphic_key_pressure( std::uint8_t channel, std::uint8_t key,
34  std::uint8_t pressure ) noexcept
35  {
36  SEQUENCER_ASSERT( channel < 16 );
37  SEQUENCER_ASSERT( key < 128 );
38  SEQUENCER_ASSERT( pressure < 128 );
39 
40  return {status_byte_for( byte::polymorphic_key_pressure, channel ), std::byte{key},
41  std::byte{pressure}};
42  }
43 
44  constexpr message_t< 3 > control_change( std::uint8_t channel, std::byte controller,
45  std::byte value ) noexcept
46  {
47  SEQUENCER_ASSERT( channel < 16 );
48 
49  return {status_byte_for( byte::control_change, channel ), controller, value};
50  }
51 
52  constexpr message_t< 3 > control_change( std::uint8_t channel, std::uint8_t controller,
53  std::uint8_t value ) noexcept
54  {
55  SEQUENCER_ASSERT( channel < 16 );
56  SEQUENCER_ASSERT( controller < 120 );
57  SEQUENCER_ASSERT( value < 128 );
58 
59  return control_change( channel, std::byte{controller}, std::byte{value} );
60  }
61 
62  constexpr message_t< 2 > program_change( std::uint8_t channel, std::uint8_t program ) noexcept
63  {
64  SEQUENCER_ASSERT( channel < 16 );
65  SEQUENCER_ASSERT( program < 128 );
66 
67  return {status_byte_for( byte::program_change, channel ), std::byte{program}};
68  }
69 
70  constexpr message_t< 2 > channel_pressure( std::uint8_t channel,
71  std::uint8_t pressure ) noexcept
72  {
73  SEQUENCER_ASSERT( channel < 16 );
74  SEQUENCER_ASSERT( pressure < 128 );
75 
76  return {status_byte_for( byte::channel_pressure, channel ), std::byte{pressure}};
77  }
78 
79  constexpr message_t< 3 > pitch_bend_change( std::uint8_t channel, std::int16_t value ) noexcept
80  {
81  SEQUENCER_ASSERT( channel < 16 );
82  SEQUENCER_ASSERT( value < max_14bit / 2 );
83  SEQUENCER_ASSERT( value > -max_14bit / 2 );
84 
85  const std::int32_t offset = 8192;
86  const auto [ lsb, msb ] = uint16_to_lsb_msb( std::uint16_t( offset + value ) );
87  return {status_byte_for( byte::pitch_bend_change, channel ), lsb, msb};
88  }
89 
90  constexpr std::array< message_t< 3 >, 2 >
91  control_change_lsb_msb( std::uint8_t channel, std::byte control_function_msb,
92  std::byte control_function_lsb, std::uint16_t value )
93  {
94  const auto [ lsb, msb ] = uint16_to_lsb_msb( value );
95  return {control_change( channel, control_function_lsb, lsb ),
96  control_change( channel, control_function_msb, msb )};
97  }
98 
99  constexpr std::array< message_t< 3 >, 2 >
100  control_change_lsb_msb( std::uint8_t channel, std::byte control_function, std::uint16_t value )
101  {
102  return control_change_lsb_msb( channel, control_function, byte::cc::lsb( control_function ),
103  value );
104  }
105 
106  constexpr std::array< message_t< 3 >, 2 > bank_select( std::uint8_t channel,
107  std::uint16_t bank ) noexcept
108  {
109  return control_change_lsb_msb( channel, byte::cc::bank_select_msb, bank );
110  }
111 
112  constexpr std::tuple< message_t< 3 >, message_t< 3 >, message_t< 2 > >
113  bank_select_with_program( std::uint8_t channel, std::uint16_t bank,
114  std::uint8_t program ) noexcept
115  {
116  const auto [ lsb, msb ] = bank_select( channel, bank );
117  return {lsb, msb, program_change( channel, program )};
118  }
119 
120  constexpr std::array< message_t< 3 >, 2 > modulation_wheel( std::uint8_t channel,
121  std::uint16_t value ) noexcept
122  {
123  return control_change_lsb_msb( channel, byte::cc::modulation_wheel_msb, value );
124  }
125 
126  constexpr std::array< message_t< 3 >, 2 > breath_controller( std::uint8_t channel,
127  std::uint16_t value ) noexcept
128  {
130  }
131 
132  constexpr std::array< message_t< 3 >, 2 > foot_controller( std::uint8_t channel,
133  std::uint16_t value ) noexcept
134  {
135  return control_change_lsb_msb( channel, byte::cc::foot_controller_msb, value );
136  }
137 
138  constexpr std::array< message_t< 3 >, 2 > portamento_time( std::uint8_t channel,
139  std::uint16_t value ) noexcept
140  {
141  return control_change_lsb_msb( channel, byte::cc::portamento_time_msb, value );
142  }
143 
144  constexpr std::array< message_t< 3 >, 2 > data_entry( std::uint8_t channel,
145  std::uint16_t value ) noexcept
146  {
147  return control_change_lsb_msb( channel, byte::cc::data_entry_msb, value );
148  }
149 
150  constexpr std::array< message_t< 3 >, 2 > channel_volume( std::uint8_t channel,
151  std::uint16_t value ) noexcept
152  {
153  return control_change_lsb_msb( channel, byte::cc::channel_volume_msb, value );
154  }
155 
156  constexpr std::array< message_t< 3 >, 2 > balance( std::uint8_t channel,
157  std::uint16_t value ) noexcept
158  {
159  return control_change_lsb_msb( channel, byte::cc::balance_msb, value );
160  }
161 
162  constexpr std::array< message_t< 3 >, 2 > pan( std::uint8_t channel,
163  std::uint16_t value ) noexcept
164  {
165  return control_change_lsb_msb( channel, byte::cc::pan_msb, value );
166  }
167 
168  constexpr std::array< message_t< 3 >, 2 > expression_controller( std::uint8_t channel,
169  std::uint16_t value ) noexcept
170  {
172  }
173 
174  constexpr std::array< message_t< 3 >, 2 > effect_control( std::uint8_t id, std::uint8_t channel,
175  std::uint16_t value ) noexcept
176  {
177  SEQUENCER_ASSERT( id >= 1 );
178  SEQUENCER_ASSERT( id <= 2 );
179  const auto control_function =
181  return control_change_lsb_msb( channel, control_function, value );
182  }
183 
184  constexpr std::array< message_t< 3 >, 2 >
185  general_purpose_controller( std::uint8_t id, std::uint8_t channel,
186  std::uint16_t value ) noexcept
187  {
188  SEQUENCER_ASSERT( id >= 1 );
189  SEQUENCER_ASSERT( id <= 4 );
190  const auto control_function =
195  return control_change_lsb_msb( channel, control_function, value );
196  }
197 
198  constexpr std::array< message_t< 3 >, 2 >
199  non_registered_parameter_number( std::uint8_t channel, std::uint16_t value ) noexcept
200  {
203  }
204 
205  constexpr std::array< message_t< 3 >, 2 >
206  registered_parameter_number( std::uint8_t channel, std::uint16_t value ) noexcept
207  {
210  }
211 
212  constexpr std::byte on_off_byte( bool on ) noexcept
213  {
214  return on ? std::byte{0x7F} : std::byte{0x00};
215  }
216 
217  constexpr message_t< 3 > damper_pedal( std::uint8_t channel, bool on ) noexcept
218  {
219  return control_change( channel, byte::cc::damper_pedal, on_off_byte( on ) );
220  }
221 
222  constexpr message_t< 3 > portamento( std::uint8_t channel, bool on ) noexcept
223  {
224  return control_change( channel, byte::cc::portamento, on_off_byte( on ) );
225  }
226 
227  constexpr message_t< 3 > sostenuto( std::uint8_t channel, bool on ) noexcept
228  {
229  return control_change( channel, byte::cc::sostenuto, on_off_byte( on ) );
230  }
231 
232  constexpr message_t< 3 > soft_pedal( std::uint8_t channel, bool on ) noexcept
233  {
234  return control_change( channel, byte::cc::soft_pedal, on_off_byte( on ) );
235  }
236 
237  constexpr message_t< 3 > hold_2( std::uint8_t channel, bool on ) noexcept
238  {
239  return control_change( channel, byte::cc::hold_2, on_off_byte( on ) );
240  }
241 
242  constexpr message_t< 3 > control_change( std::uint8_t channel,
243  std::byte control_function ) noexcept
244  {
245  return control_change( channel, control_function, std::byte{0x00} );
246  }
247 
248  constexpr message_t< 3 > all_sounds_off( std::uint8_t channel ) noexcept
249  {
250  SEQUENCER_ASSERT( channel < 16 );
251  return control_change( channel, byte::cc::all_sounds_off );
252  }
253 
254  constexpr message_t< 3 > reset_all_controllers( std::uint8_t channel ) noexcept
255  {
256  SEQUENCER_ASSERT( channel < 16 );
258  }
259 
260  constexpr message_t< 3 > local_control( std::uint8_t channel, bool on ) noexcept
261  {
262  SEQUENCER_ASSERT( channel < 16 );
263  const auto data_byte = on ? std::byte{0x7F} : std::byte{0x00};
264  return control_change( channel, byte::cc::local_control, data_byte );
265  }
266 
267  constexpr message_t< 3 > all_notes_off( std::uint8_t channel ) noexcept
268  {
269  SEQUENCER_ASSERT( channel < 16 );
270  return control_change( channel, byte::cc::all_notes_off );
271  }
272 
273  constexpr message_t< 3 > omni_mode_off( std::uint8_t channel ) noexcept
274  {
275  SEQUENCER_ASSERT( channel < 16 );
276  return control_change( channel, byte::cc::omni_mode_off );
277  }
278 
279  constexpr message_t< 3 > omni_mode_on( std::uint8_t channel ) noexcept
280  {
281  SEQUENCER_ASSERT( channel < 16 );
282  return control_change( channel, byte::cc::omni_mode_on );
283  }
284 
285  constexpr message_t< 3 > poly_mode_on( std::uint8_t channel ) noexcept
286  {
287  SEQUENCER_ASSERT( channel < 16 );
288  return control_change( channel, byte::cc::poly_mode_on );
289  }
290 
291  constexpr message_t< 3 > effects_1_depth( std::uint8_t channel, std::uint8_t value ) noexcept
292  {
293  SEQUENCER_ASSERT( channel < 16 );
294  SEQUENCER_ASSERT( value < 128 );
295  return control_change( channel, byte::cc::effects_1_depth, std::byte{value} );
296  }
297 
298  constexpr message_t< 3 > effects_2_depth( std::uint8_t channel, std::uint8_t value ) noexcept
299  {
300  SEQUENCER_ASSERT( channel < 16 );
301  SEQUENCER_ASSERT( value < 128 );
302  return control_change( channel, byte::cc::effects_2_depth, std::byte{value} );
303  }
304 
305  constexpr message_t< 3 > effects_3_depth( std::uint8_t channel, std::uint8_t value ) noexcept
306  {
307  SEQUENCER_ASSERT( channel < 16 );
308  SEQUENCER_ASSERT( value < 128 );
309  return control_change( channel, byte::cc::effects_3_depth, std::byte{value} );
310  }
311 
312  constexpr message_t< 3 > effects_4_depth( std::uint8_t channel, std::uint8_t value ) noexcept
313  {
314  SEQUENCER_ASSERT( channel < 16 );
315  SEQUENCER_ASSERT( value < 128 );
316  return control_change( channel, byte::cc::effects_4_depth, std::byte{value} );
317  }
318 
319  constexpr message_t< 3 > effects_5_depth( std::uint8_t channel, std::uint8_t value ) noexcept
320  {
321  SEQUENCER_ASSERT( channel < 16 );
322  SEQUENCER_ASSERT( value < 128 );
323  return control_change( channel, byte::cc::effects_5_depth, std::byte{value} );
324  }
325 } // namespace sequencer::midi::channel::voice
constexpr auto sostenuto
Definition: byte.hpp:77
constexpr auto non_registered_parameter_number_msb
Definition: byte.hpp:86
constexpr message_t< 3 > polymorphic_key_pressure(std::uint8_t channel, std::uint8_t key, std::uint8_t pressure) noexcept
Definition: channel_voice.hpp:33
constexpr message_t< 3 > soft_pedal(std::uint8_t channel, bool on) noexcept
Definition: channel_voice.hpp:232
constexpr std::array< message_t< 3 >, 2 > control_change_lsb_msb(std::uint8_t channel, std::byte control_function_msb, std::byte control_function_lsb, std::uint16_t value)
Definition: channel_voice.hpp:91
constexpr std::array< message_t< 3 >, 2 > general_purpose_controller(std::uint8_t id, std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:185
constexpr auto balance_msb
Definition: byte.hpp:57
constexpr auto channel_pressure
Definition: byte.hpp:14
constexpr auto expression_controller_msb
Definition: byte.hpp:61
constexpr auto breath_controller_msb
Definition: byte.hpp:47
constexpr message_t< 3 > effects_1_depth(std::uint8_t channel, std::uint8_t value) noexcept
Definition: channel_voice.hpp:291
constexpr auto channel_volume_msb
Definition: byte.hpp:55
constexpr auto all_sounds_off
Definition: byte.hpp:89
constexpr message_t< 3 > effects_2_depth(std::uint8_t channel, std::uint8_t value) noexcept
Definition: channel_voice.hpp:298
constexpr auto reset_all_controllers
Definition: byte.hpp:90
constexpr auto registered_parameter_number_msb
Definition: byte.hpp:88
constexpr std::array< message_t< 3 >, 2 > expression_controller(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:168
constexpr auto foot_controller_msb
Definition: byte.hpp:49
constexpr std::array< message_t< 3 >, 2 > bank_select(std::uint8_t channel, std::uint16_t bank) noexcept
Definition: channel_voice.hpp:106
constexpr auto effect_control_1_msb
Definition: byte.hpp:63
constexpr message_t< 3 > damper_pedal(std::uint8_t channel, bool on) noexcept
Definition: channel_voice.hpp:217
std::conditional_t< greater_than< number_of_bytes, 0 >::value, std::array< std::byte, number_of_bytes >, std::vector< std::byte > > message_t
Definition: message_type.hpp:18
constexpr auto polymorphic_key_pressure
Definition: byte.hpp:11
#define SEQUENCER_ASSERT(cond)
Definition: assert.hpp:8
constexpr std::array< message_t< 3 >, 2 > modulation_wheel(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:120
constexpr auto program_change
Definition: byte.hpp:13
constexpr message_t< 3 > note_on(std::uint8_t channel, std::uint8_t note, std::uint8_t velocity) noexcept
Definition: channel_voice.hpp:13
constexpr auto lsb(std::byte msb)
Definition: byte.hpp:37
constexpr message_t< 2 > program_change(std::uint8_t channel, std::uint8_t program) noexcept
Definition: channel_voice.hpp:62
constexpr message_t< 3 > all_notes_off(std::uint8_t channel) noexcept
Definition: channel_voice.hpp:267
constexpr message_t< 3 > omni_mode_off(std::uint8_t channel) noexcept
Definition: channel_voice.hpp:273
constexpr message_t< 3 > control_change(std::uint8_t channel, std::byte controller, std::byte value) noexcept
Definition: channel_voice.hpp:44
constexpr std::array< message_t< 3 >, 2 > non_registered_parameter_number(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:199
constexpr message_t< 3 > note_off(std::uint8_t channel, std::uint8_t note, std::uint8_t velocity) noexcept
Definition: channel_voice.hpp:23
constexpr std::array< message_t< 3 >, 2 > balance(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:156
constexpr auto pan_msb
Definition: byte.hpp:59
constexpr message_t< 3 > effects_5_depth(std::uint8_t channel, std::uint8_t value) noexcept
Definition: channel_voice.hpp:319
constexpr auto effects_4_depth
Definition: byte.hpp:83
constexpr auto portamento_time_msb
Definition: byte.hpp:51
constexpr std::array< message_t< 3 >, 2 > portamento_time(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:138
constexpr auto hold_2
Definition: byte.hpp:79
constexpr auto bank_select_msb
Definition: byte.hpp:43
constexpr message_t< 3 > hold_2(std::uint8_t channel, bool on) noexcept
Definition: channel_voice.hpp:237
constexpr auto omni_mode_on
Definition: byte.hpp:94
constexpr message_t< 2 > channel_pressure(std::uint8_t channel, std::uint8_t pressure) noexcept
Definition: channel_voice.hpp:70
constexpr message_t< 3 > effects_4_depth(std::uint8_t channel, std::uint8_t value) noexcept
Definition: channel_voice.hpp:312
constexpr auto data_entry_msb
Definition: byte.hpp:53
constexpr std::array< message_t< 3 >, 2 > breath_controller(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:126
constexpr auto effects_3_depth
Definition: byte.hpp:82
constexpr auto omni_mode_off
Definition: byte.hpp:93
constexpr message_t< 3 > sostenuto(std::uint8_t channel, bool on) noexcept
Definition: channel_voice.hpp:227
constexpr auto local_control
Definition: byte.hpp:91
constexpr auto damper_pedal
Definition: byte.hpp:75
constexpr auto effects_5_depth
Definition: byte.hpp:84
constexpr auto effects_2_depth
Definition: byte.hpp:81
constexpr auto soft_pedal
Definition: byte.hpp:78
constexpr auto general_purpose_controller_1_msb
Definition: byte.hpp:67
Definition: channel_voice.hpp:11
constexpr auto non_registered_parameter_number_lsb
Definition: byte.hpp:85
constexpr message_t< 3 > local_control(std::uint8_t channel, bool on) noexcept
Definition: channel_voice.hpp:260
constexpr std::array< message_t< 3 >, 2 > data_entry(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:144
constexpr auto note_on
Definition: byte.hpp:9
constexpr auto modulation_wheel_msb
Definition: byte.hpp:45
constexpr message_t< 3 > pitch_bend_change(std::uint8_t channel, std::int16_t value) noexcept
Definition: channel_voice.hpp:79
constexpr auto general_purpose_controller_4_msb
Definition: byte.hpp:73
constexpr std::array< message_t< 3 >, 2 > pan(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:162
constexpr std::byte status_byte_for(std::byte status_byte, std::uint8_t channel) noexcept
Definition: util.hpp:16
constexpr auto all_notes_off
Definition: byte.hpp:92
constexpr std::array< message_t< 3 >, 2 > foot_controller(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:132
constexpr auto poly_mode_on
Definition: byte.hpp:95
constexpr std::byte on_off_byte(bool on) noexcept
Definition: channel_voice.hpp:212
constexpr std::pair< std::byte, std::byte > uint16_to_lsb_msb(std::uint16_t value) noexcept
Definition: util.hpp:34
constexpr auto note_off
Definition: byte.hpp:10
constexpr auto pitch_bend_change
Definition: byte.hpp:15
constexpr message_t< 3 > omni_mode_on(std::uint8_t channel) noexcept
Definition: channel_voice.hpp:279
constexpr std::array< message_t< 3 >, 2 > registered_parameter_number(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:206
constexpr std::tuple< message_t< 3 >, message_t< 3 >, message_t< 2 > > bank_select_with_program(std::uint8_t channel, std::uint16_t bank, std::uint8_t program) noexcept
Definition: channel_voice.hpp:113
constexpr auto registered_parameter_number_lsb
Definition: byte.hpp:87
constexpr auto effects_1_depth
Definition: byte.hpp:80
constexpr message_t< 3 > all_sounds_off(std::uint8_t channel) noexcept
Definition: channel_voice.hpp:248
constexpr message_t< 3 > portamento(std::uint8_t channel, bool on) noexcept
Definition: channel_voice.hpp:222
constexpr std::array< message_t< 3 >, 2 > effect_control(std::uint8_t id, std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:174
constexpr auto general_purpose_controller_2_msb
Definition: byte.hpp:69
constexpr message_t< 3 > poly_mode_on(std::uint8_t channel) noexcept
Definition: channel_voice.hpp:285
constexpr message_t< 3 > effects_3_depth(std::uint8_t channel, std::uint8_t value) noexcept
Definition: channel_voice.hpp:305
constexpr auto control_change
Definition: byte.hpp:12
constexpr message_t< 3 > reset_all_controllers(std::uint8_t channel) noexcept
Definition: channel_voice.hpp:254
constexpr auto effect_control_2_msb
Definition: byte.hpp:65
constexpr auto general_purpose_controller_3_msb
Definition: byte.hpp:71
constexpr auto portamento
Definition: byte.hpp:76
constexpr std::array< message_t< 3 >, 2 > channel_volume(std::uint8_t channel, std::uint16_t value) noexcept
Definition: channel_voice.hpp:150