1 //midi for embedded chips,
2 //Copyright 2010 Alex Norman
4 //This file is part of avr-midi.
6 //avr-midi is free software: you can redistribute it and/or modify
7 //it under the terms of the GNU General Public License as published by
8 //the Free Software Foundation, either version 3 of the License, or
9 //(at your option) any later version.
11 //avr-midi is distributed in the hope that it will be useful,
12 //but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 //GNU General Public License for more details.
16 //You should have received a copy of the GNU General Public License
17 //along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
21 * @brief The main midi functions
23 * This file includes all of the functions you need to set up and process a
24 * midi device, send midi, and register midi callbacks.
35 #include "midi_device.h"
36 #include "midi_function_types.h"
39 * @defgroup midi_device_setup_process Device initialization and processing
40 * @brief These are method that you must use to initialize and run a device
46 * @brief Initialize a device
48 * You must call this before using the device in question.
50 * @param device the device to initialize
52 void midi_device_init(MidiDevice * device); // [implementation in midi_device.c]
55 * @brief Process input data
57 * This method drives the input processing, you must call this method frequently
58 * if you expect to have your input callbacks called.
60 * @param device the device to process
62 void midi_device_process(MidiDevice * device); // [implementation in midi_device.c]
67 * @defgroup send_functions Midi send functions
68 * @brief These are the functions you use to send midi data through a device.
73 * @brief Send a control change message (cc) via the given device.
75 * @param device the device to use for sending
76 * @param chan the channel to send on, 0-15
77 * @param num the cc num
78 * @param val the value of that cc num
80 void midi_send_cc(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t val);
83 * @brief Send a note on message via the given device.
85 * @param device the device to use for sending
86 * @param chan the channel to send on, 0-15
87 * @param num the note number
88 * @param vel the note velocity
90 void midi_send_noteon(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t vel);
93 * @brief Send a note off message via the given device.
95 * @param device the device to use for sending
96 * @param chan the channel to send on, 0-15
97 * @param num the note number
98 * @param vel the note velocity
100 void midi_send_noteoff(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t vel);
103 * @brief Send an after touch message via the given device.
105 * @param device the device to use for sending
106 * @param chan the channel to send on, 0-15
107 * @param note_num the note number
108 * @param amt the after touch amount
110 void midi_send_aftertouch(MidiDevice * device, uint8_t chan, uint8_t note_num, uint8_t amt);
113 * @brief Send a pitch bend message via the given device.
115 * @param device the device to use for sending
116 * @param chan the channel to send on, 0-15
117 * @param amt the bend amount range: -8192..8191, 0 means no bend
119 void midi_send_pitchbend(MidiDevice * device, uint8_t chan, int16_t amt); //range -8192, 8191
122 * @brief Send a program change message via the given device.
124 * @param device the device to use for sending
125 * @param chan the channel to send on, 0-15
126 * @param num the program to change to
128 void midi_send_programchange(MidiDevice * device, uint8_t chan, uint8_t num);
131 * @brief Send a channel pressure message via the given device.
133 * @param device the device to use for sending
134 * @param chan the channel to send on, 0-15
135 * @param amt the amount of channel pressure
137 void midi_send_channelpressure(MidiDevice * device, uint8_t chan, uint8_t amt);
140 * @brief Send a clock message via the given device.
142 * @param device the device to use for sending
144 void midi_send_clock(MidiDevice * device);
147 * @brief Send a tick message via the given device.
149 * @param device the device to use for sending
151 void midi_send_tick(MidiDevice * device);
154 * @brief Send a start message via the given device.
156 * @param device the device to use for sending
158 void midi_send_start(MidiDevice * device);
161 * @brief Send a continue message via the given device.
163 * @param device the device to use for sending
165 void midi_send_continue(MidiDevice * device);
168 * @brief Send a stop message via the given device.
170 * @param device the device to use for sending
172 void midi_send_stop(MidiDevice * device);
175 * @brief Send an active sense message via the given device.
177 * @param device the device to use for sending
179 void midi_send_activesense(MidiDevice * device);
182 * @brief Send a reset message via the given device.
184 * @param device the device to use for sending
186 void midi_send_reset(MidiDevice * device);
190 * @brief Send a tc quarter frame message via the given device.
192 * @param device the device to use for sending
193 * @param time the time of this quarter frame, range 0..16383
195 void midi_send_tcquarterframe(MidiDevice * device, uint8_t time);
198 * @brief Send a song position message via the given device.
200 * @param device the device to use for sending
201 * @param pos the song position
203 void midi_send_songposition(MidiDevice * device, uint16_t pos);
206 * @brief Send a song select message via the given device.
208 * @param device the device to use for sending
209 * @param song the song to select
211 void midi_send_songselect(MidiDevice * device, uint8_t song);
214 * @brief Send a tune request message via the given device.
216 * @param device the device to use for sending
218 void midi_send_tunerequest(MidiDevice * device);
221 * @brief Send a byte via the given device.
223 * This is a generic method for sending data via the given midi device.
224 * This would be useful for sending sysex data or messages that are not
225 * implemented in this API, if there are any. Please contact the author
226 * if you find some so we can add them.
228 * @param device the device to use for sending
229 * @param b the byte to send
231 void midi_send_byte(MidiDevice * device, uint8_t b);
234 * @brief Send up to 3 bytes of data
236 * % 4 is applied to count so that you can use this to pass sysex through
238 * @param device the device to use for sending
239 * @param count the count of bytes to send, %4 is applied
240 * @param byte0 the first byte
241 * @param byte1 the second byte, ignored if cnt % 4 != 2
242 * @param byte2 the third byte, ignored if cnt % 4 != 3
244 void midi_send_data(MidiDevice * device, uint16_t count, uint8_t byte0, uint8_t byte1, uint8_t byte2);
247 * @brief Send an array of formatted midi data.
249 * Can be used for sysex.
251 * @param device the device to use for sending
252 * @param count the count of bytes to send
253 * @param array the array of bytes
255 void midi_send_array(MidiDevice * device, uint16_t count, uint8_t * array);
261 * @defgroup input_callback_reg Input callback registration functions
263 * @brief These are the functions you use to register your input callbacks.
265 * The functions are called when the appropriate midi message is matched on the
266 * associated device's input.
274 * @brief Register a control change message (cc) callback.
276 * @param device the device associate with
277 * @param func the callback function to register
279 void midi_register_cc_callback(MidiDevice * device, midi_three_byte_func_t func);
282 * @brief Register a note on callback.
284 * @param device the device associate with
285 * @param func the callback function to register
287 void midi_register_noteon_callback(MidiDevice * device, midi_three_byte_func_t func);
290 * @brief Register a note off callback.
292 * @param device the device associate with
293 * @param func the callback function to register
295 void midi_register_noteoff_callback(MidiDevice * device, midi_three_byte_func_t func);
298 * @brief Register an after touch callback.
300 * @param device the device associate with
301 * @param func the callback function to register
304 void midi_register_aftertouch_callback(MidiDevice * device, midi_three_byte_func_t func);
307 * @brief Register a pitch bend callback.
309 * @param device the device associate with
310 * @param func the callback function to register
312 void midi_register_pitchbend_callback(MidiDevice * device, midi_three_byte_func_t func);
315 * @brief Register a song position callback.
317 * @param device the device associate with
318 * @param func the callback function to register
320 void midi_register_songposition_callback(MidiDevice * device, midi_three_byte_func_t func);
325 * @brief Register a program change callback.
327 * @param device the device associate with
328 * @param func the callback function to register
330 void midi_register_progchange_callback(MidiDevice * device, midi_two_byte_func_t func);
333 * @brief Register a channel pressure callback.
335 * @param device the device associate with
336 * @param func the callback function to register
338 void midi_register_chanpressure_callback(MidiDevice * device, midi_two_byte_func_t func);
341 * @brief Register a song select callback.
343 * @param device the device associate with
344 * @param func the callback function to register
346 void midi_register_songselect_callback(MidiDevice * device, midi_two_byte_func_t func);
349 * @brief Register a tc quarter frame callback.
351 * @param device the device associate with
352 * @param func the callback function to register
354 void midi_register_tc_quarterframe_callback(MidiDevice * device, midi_two_byte_func_t func);
359 * @brief Register a realtime callback.
361 * The callback will be called for all of the real time message types.
363 * @param device the device associate with
364 * @param func the callback function to register
366 void midi_register_realtime_callback(MidiDevice * device, midi_one_byte_func_t func);
369 * @brief Register a tune request callback.
371 * @param device the device associate with
372 * @param func the callback function to register
374 void midi_register_tunerequest_callback(MidiDevice * device, midi_one_byte_func_t func);
377 * @brief Register a sysex callback.
379 * @param device the device associate with
380 * @param func the callback function to register
382 void midi_register_sysex_callback(MidiDevice * device, midi_sysex_func_t func);
385 * @brief Register fall through callback.
387 * This is only called if a more specific callback is not matched and called.
388 * For instance, if you don't register a note on callback but you get a note on message
389 * the fall through callback will be called, if it is registered.
391 * @param device the device associate with
392 * @param func the callback function to register
394 void midi_register_fallthrough_callback(MidiDevice * device, midi_var_byte_func_t func);
398 * @brief Register a catch all callback.
400 * If registered, the catch all callback is called for every message that is
401 * matched, even if a more specific or the fallthrough callback is registered.
403 * @param device the device associate with
404 * @param func the callback function to register
406 void midi_register_catchall_callback(MidiDevice * device, midi_var_byte_func_t func);
411 * @defgroup midi_util Device independent utility functions.
416 * \enum midi_packet_length_t
418 * An enumeration of the possible packet length values.
424 THREE = 3} midi_packet_length_t;
427 * @brief Test to see if the byte given is a status byte
428 * @param theByte the byte to test
429 * @return true if the byte given is a midi status byte
431 bool midi_is_statusbyte(uint8_t theByte);
434 * @brief Test to see if the byte given is a realtime message
435 * @param theByte the byte to test
436 * @return true if it is a realtime message, false otherwise
438 bool midi_is_realtime(uint8_t theByte);
441 * @brief Find the length of the packet associated with the status byte given
442 * @param status the status byte
443 * @return the length of the packet, will return UNDEFINED if the byte is not
444 * a status byte or if it is a sysex status byte
446 midi_packet_length_t midi_packet_length(uint8_t status);
451 * @defgroup defines Midi status and miscellaneous utility #defines
456 #define SYSEX_BEGIN 0xF0
457 #define SYSEX_END 0xF7
459 //if you and this with a byte and you get anything non-zero
460 //it is a status message
461 #define MIDI_STATUSMASK 0x80
462 //if you and this with a status message that contains channel info,
463 //you'll get the channel
464 #define MIDI_CHANMASK 0x0F
467 #define MIDI_NOTEON 0x90
468 #define MIDI_NOTEOFF 0x80
469 #define MIDI_AFTERTOUCH 0xA0
470 #define MIDI_PITCHBEND 0xE0
471 #define MIDI_PROGCHANGE 0xC0
472 #define MIDI_CHANPRESSURE 0xD0
475 #define MIDI_CLOCK 0xF8
476 #define MIDI_TICK 0xF9
477 #define MIDI_START 0xFA
478 #define MIDI_CONTINUE 0xFB
479 #define MIDI_STOP 0xFC
480 #define MIDI_ACTIVESENSE 0xFE
481 #define MIDI_RESET 0xFF
483 #define MIDI_TC_QUARTERFRAME 0xF1
484 #define MIDI_SONGPOSITION 0xF2
485 #define MIDI_SONGSELECT 0xF3
486 #define MIDI_TUNEREQUEST 0xF6
488 //This ID is for educational or development use only
489 #define SYSEX_EDUMANUFID 0x7D