2019-08-30 20:19:03 +02:00
|
|
|
// midi for embedded chips,
|
|
|
|
// Copyright 2010 Alex Norman
|
2015-08-20 06:42:28 +02:00
|
|
|
//
|
2019-08-30 20:19:03 +02:00
|
|
|
// This file is part of avr-midi.
|
2015-08-20 06:42:28 +02:00
|
|
|
//
|
2019-08-30 20:19:03 +02:00
|
|
|
// avr-midi is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
2015-08-20 06:42:28 +02:00
|
|
|
//(at your option) any later version.
|
|
|
|
//
|
2019-08-30 20:19:03 +02:00
|
|
|
// avr-midi is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
2015-08-20 06:42:28 +02:00
|
|
|
//
|
2019-08-30 20:19:03 +02:00
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
|
2015-08-20 06:42:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @brief Device implementation functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef MIDI_DEVICE_H
|
|
|
|
#define MIDI_DEVICE_H
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
2019-08-30 20:19:03 +02:00
|
|
|
#endif
|
2015-08-20 06:42:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @defgroup midi_device Functions used when implementing your own midi device.
|
|
|
|
*
|
|
|
|
* You use the functions when you are implementing your own midi device.
|
|
|
|
*
|
|
|
|
* You set a send function to actually send bytes via your device, this method
|
|
|
|
* is called when you call a send function with this device, for instance
|
|
|
|
* midi_send_cc
|
|
|
|
*
|
|
|
|
* You use the midi_device_input to process input data from the device and pass
|
|
|
|
* it through the device's associated callbacks.
|
|
|
|
*
|
|
|
|
* You use the midi_device_set_pre_input_process_func if you want to have a
|
|
|
|
* function called at the beginning of the device's process function, generally
|
|
|
|
* to poll for input and pass that into midi_device_input
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "midi_function_types.h"
|
|
|
|
#include "bytequeue/bytequeue.h"
|
|
|
|
#define MIDI_INPUT_QUEUE_LENGTH 192
|
|
|
|
|
2019-08-30 20:19:03 +02:00
|
|
|
typedef enum { IDLE, ONE_BYTE_MESSAGE = 1, TWO_BYTE_MESSAGE = 2, THREE_BYTE_MESSAGE = 3, SYSEX_MESSAGE } input_state_t;
|
2015-08-20 06:42:28 +02:00
|
|
|
|
2019-08-30 20:19:03 +02:00
|
|
|
typedef void (*midi_no_byte_func_t)(MidiDevice* device);
|
2015-08-20 06:42:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \struct _midi_device
|
|
|
|
*
|
|
|
|
* @brief This structure represents the input and output functions and
|
|
|
|
* processing data for a midi device.
|
|
|
|
*
|
|
|
|
* A device can represent an actual physical device [serial port, usb port] or
|
|
|
|
* something virtual.
|
|
|
|
* You should not need to modify this structure directly.
|
|
|
|
*/
|
|
|
|
struct _midi_device {
|
2019-08-30 20:19:03 +02:00
|
|
|
// output send function
|
|
|
|
midi_var_byte_func_t send_func;
|
|
|
|
|
|
|
|
//********input callbacks
|
|
|
|
// three byte funcs
|
|
|
|
midi_three_byte_func_t input_cc_callback;
|
|
|
|
midi_three_byte_func_t input_noteon_callback;
|
|
|
|
midi_three_byte_func_t input_noteoff_callback;
|
|
|
|
midi_three_byte_func_t input_aftertouch_callback;
|
|
|
|
midi_three_byte_func_t input_pitchbend_callback;
|
|
|
|
midi_three_byte_func_t input_songposition_callback;
|
|
|
|
// two byte funcs
|
|
|
|
midi_two_byte_func_t input_progchange_callback;
|
|
|
|
midi_two_byte_func_t input_chanpressure_callback;
|
|
|
|
midi_two_byte_func_t input_songselect_callback;
|
|
|
|
midi_two_byte_func_t input_tc_quarterframe_callback;
|
|
|
|
// one byte funcs
|
|
|
|
midi_one_byte_func_t input_realtime_callback;
|
|
|
|
midi_one_byte_func_t input_tunerequest_callback;
|
|
|
|
|
|
|
|
// sysex
|
|
|
|
midi_sysex_func_t input_sysex_callback;
|
|
|
|
|
|
|
|
// only called if more specific callback is not matched
|
|
|
|
midi_var_byte_func_t input_fallthrough_callback;
|
|
|
|
// called if registered, independent of other callbacks
|
|
|
|
midi_var_byte_func_t input_catchall_callback;
|
|
|
|
|
|
|
|
// pre input processing function
|
|
|
|
midi_no_byte_func_t pre_input_process_callback;
|
|
|
|
|
|
|
|
// for internal input processing
|
|
|
|
uint8_t input_buffer[3];
|
|
|
|
input_state_t input_state;
|
|
|
|
uint16_t input_count;
|
|
|
|
|
|
|
|
// for queueing data between the input and the processing functions
|
|
|
|
uint8_t input_queue_data[MIDI_INPUT_QUEUE_LENGTH];
|
|
|
|
byteQueue_t input_queue;
|
2015-08-20 06:42:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Process input bytes. This function parses bytes and calls the
|
|
|
|
* appropriate callbacks associated with the given device. You use this
|
|
|
|
* function if you are creating a custom device and you want to have midi
|
|
|
|
* input.
|
|
|
|
*
|
|
|
|
* @param device the midi device to associate the input with
|
|
|
|
* @param cnt the number of bytes you are processing
|
|
|
|
* @param input the bytes to process
|
|
|
|
*/
|
2019-08-30 20:19:03 +02:00
|
|
|
void midi_device_input(MidiDevice* device, uint8_t cnt, uint8_t* input);
|
2015-08-20 06:42:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set the callback function that will be used for sending output
|
|
|
|
* data bytes. This is only used if you're creating a custom device.
|
|
|
|
* You'll most likely want the callback function to disable interrupts so
|
|
|
|
* that you can call the various midi send functions without worrying about
|
|
|
|
* locking.
|
|
|
|
*
|
|
|
|
* \param device the midi device to associate this callback with
|
|
|
|
* \param send_func the callback function that will do the sending
|
|
|
|
*/
|
2019-08-30 20:19:03 +02:00
|
|
|
void midi_device_set_send_func(MidiDevice* device, midi_var_byte_func_t send_func);
|
2015-08-20 06:42:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set a callback which is called at the beginning of the
|
|
|
|
* midi_device_process call. This can be used to poll for input
|
|
|
|
* data and send the data through the midi_device_input function.
|
|
|
|
* You'll probably only use this if you're creating a custom device.
|
|
|
|
*
|
|
|
|
* \param device the midi device to associate this callback with
|
|
|
|
* \param midi_no_byte_func_t the actual callback function
|
|
|
|
*/
|
2019-08-30 20:19:03 +02:00
|
|
|
void midi_device_set_pre_input_process_func(MidiDevice* device, midi_no_byte_func_t pre_process_func);
|
2015-08-20 06:42:28 +02:00
|
|
|
|
|
|
|
/**@}*/
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
2019-08-30 20:19:03 +02:00
|
|
|
#endif
|
2015-08-20 06:42:28 +02:00
|
|
|
|
|
|
|
#endif
|