daily_automated
This commit is contained in:
15
trunk/Arduino/libraries/MIDI_Library/src/CMakeLists.txt
Normal file
15
trunk/Arduino/libraries/MIDI_Library/src/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
increase_warning_level()
|
||||
|
||||
project(midi)
|
||||
|
||||
add_library(midi STATIC
|
||||
midi_Namespace.h
|
||||
midi_Defs.h
|
||||
midi_Message.h
|
||||
midi_Platform.h
|
||||
midi_Settings.h
|
||||
MIDI.cpp
|
||||
MIDI.hpp
|
||||
MIDI.h
|
||||
serialMIDI.h
|
||||
)
|
||||
115
trunk/Arduino/libraries/MIDI_Library/src/MIDI.cpp
Normal file
115
trunk/Arduino/libraries/MIDI_Library/src/MIDI.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/*!
|
||||
* @file MIDI.cpp
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino
|
||||
* @author Francois Best
|
||||
* @date 24/02/11
|
||||
* @license MIT - Copyright (c) 2015 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "MIDI.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
/*! \brief Encode System Exclusive messages.
|
||||
SysEx messages are encoded to guarantee transmission of data bytes higher than
|
||||
127 without breaking the MIDI protocol. Use this static method to convert the
|
||||
data you want to send.
|
||||
\param inData The data to encode.
|
||||
\param outSysEx The output buffer where to store the encoded message.
|
||||
\param inLength The length of the input buffer.
|
||||
\param inFlipHeaderBits True for Korg and other who store MSB in reverse order
|
||||
\return The length of the encoded output buffer.
|
||||
@see decodeSysEx
|
||||
Code inspired from Ruin & Wesen's SysEx encoder/decoder - http://ruinwesen.com
|
||||
*/
|
||||
unsigned encodeSysEx(const byte* inData,
|
||||
byte* outSysEx,
|
||||
unsigned inLength,
|
||||
bool inFlipHeaderBits)
|
||||
{
|
||||
unsigned outLength = 0; // Num bytes in output array.
|
||||
byte count = 0; // Num 7bytes in a block.
|
||||
outSysEx[0] = 0;
|
||||
|
||||
for (unsigned i = 0; i < inLength; ++i)
|
||||
{
|
||||
const byte data = inData[i];
|
||||
const byte msb = data >> 7;
|
||||
const byte body = data & 0x7f;
|
||||
|
||||
outSysEx[0] |= (msb << (inFlipHeaderBits ? count : (6 - count)));
|
||||
outSysEx[1 + count] = body;
|
||||
|
||||
if (count++ == 6)
|
||||
{
|
||||
outSysEx += 8;
|
||||
outLength += 8;
|
||||
outSysEx[0] = 0;
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
return outLength + count + (count != 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
/*! \brief Decode System Exclusive messages.
|
||||
SysEx messages are encoded to guarantee transmission of data bytes higher than
|
||||
127 without breaking the MIDI protocol. Use this static method to reassemble
|
||||
your received message.
|
||||
\param inSysEx The SysEx data received from MIDI in.
|
||||
\param outData The output buffer where to store the decrypted message.
|
||||
\param inLength The length of the input buffer.
|
||||
\param inFlipHeaderBits True for Korg and other who store MSB in reverse order
|
||||
\return The length of the output buffer.
|
||||
@see encodeSysEx @see getSysExArrayLength
|
||||
Code inspired from Ruin & Wesen's SysEx encoder/decoder - http://ruinwesen.com
|
||||
*/
|
||||
unsigned decodeSysEx(const byte* inSysEx,
|
||||
byte* outData,
|
||||
unsigned inLength,
|
||||
bool inFlipHeaderBits)
|
||||
{
|
||||
unsigned count = 0;
|
||||
byte msbStorage = 0;
|
||||
byte byteIndex = 0;
|
||||
|
||||
for (unsigned i = 0; i < inLength; ++i)
|
||||
{
|
||||
if ((i % 8) == 0)
|
||||
{
|
||||
msbStorage = inSysEx[i];
|
||||
byteIndex = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
const byte body = inSysEx[i];
|
||||
const byte shift = inFlipHeaderBits ? 6 - byteIndex : byteIndex;
|
||||
const byte msb = byte(((msbStorage >> shift) & 1) << 7);
|
||||
byteIndex--;
|
||||
outData[count++] = msb | body;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
307
trunk/Arduino/libraries/MIDI_Library/src/MIDI.h
Normal file
307
trunk/Arduino/libraries/MIDI_Library/src/MIDI.h
Normal file
@@ -0,0 +1,307 @@
|
||||
/*!
|
||||
* @file MIDI.h
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino
|
||||
* @author Francois Best, lathoub
|
||||
* @date 24/02/11
|
||||
* @license MIT - Copyright (c) 2015 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "midi_Defs.h"
|
||||
#include "midi_Platform.h"
|
||||
#include "midi_Settings.h"
|
||||
#include "midi_Message.h"
|
||||
|
||||
#include "serialMIDI.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
#define MIDI_LIBRARY_VERSION 0x050000
|
||||
#define MIDI_LIBRARY_VERSION_MAJOR 5
|
||||
#define MIDI_LIBRARY_VERSION_MINOR 0
|
||||
#define MIDI_LIBRARY_VERSION_PATCH 0
|
||||
|
||||
/*! \brief The main class for MIDI handling.
|
||||
It is templated over the type of serial port to provide abstraction from
|
||||
the hardware interface, meaning you can use HardwareSerial, SoftwareSerial
|
||||
or ak47's Uart classes. The only requirement is that the class implements
|
||||
the begin, read, write and available methods.
|
||||
*/
|
||||
template<class Transport, class _Settings = DefaultSettings, class _Platform = DefaultPlatform>
|
||||
class MidiInterface
|
||||
{
|
||||
public:
|
||||
typedef _Settings Settings;
|
||||
typedef _Platform Platform;
|
||||
typedef Message<Settings::SysExMaxSize> MidiMessage;
|
||||
|
||||
public:
|
||||
inline MidiInterface(Transport&);
|
||||
inline ~MidiInterface();
|
||||
|
||||
public:
|
||||
void begin(Channel inChannel = 1);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// MIDI Output
|
||||
|
||||
public:
|
||||
inline void sendNoteOn(DataByte inNoteNumber,
|
||||
DataByte inVelocity,
|
||||
Channel inChannel);
|
||||
|
||||
inline void sendNoteOff(DataByte inNoteNumber,
|
||||
DataByte inVelocity,
|
||||
Channel inChannel);
|
||||
|
||||
inline void sendProgramChange(DataByte inProgramNumber,
|
||||
Channel inChannel);
|
||||
|
||||
inline void sendControlChange(DataByte inControlNumber,
|
||||
DataByte inControlValue,
|
||||
Channel inChannel);
|
||||
|
||||
inline void sendPitchBend(int inPitchValue, Channel inChannel);
|
||||
inline void sendPitchBend(double inPitchValue, Channel inChannel);
|
||||
|
||||
inline void sendPolyPressure(DataByte inNoteNumber,
|
||||
DataByte inPressure,
|
||||
Channel inChannel) __attribute__ ((deprecated));
|
||||
|
||||
inline void sendAfterTouch(DataByte inPressure,
|
||||
Channel inChannel);
|
||||
inline void sendAfterTouch(DataByte inNoteNumber,
|
||||
DataByte inPressure,
|
||||
Channel inChannel);
|
||||
|
||||
inline void sendSysEx(unsigned inLength,
|
||||
const byte* inArray,
|
||||
bool inArrayContainsBoundaries = false);
|
||||
|
||||
inline void sendTimeCodeQuarterFrame(DataByte inTypeNibble,
|
||||
DataByte inValuesNibble);
|
||||
inline void sendTimeCodeQuarterFrame(DataByte inData);
|
||||
|
||||
inline void sendSongPosition(unsigned inBeats);
|
||||
inline void sendSongSelect(DataByte inSongNumber);
|
||||
inline void sendTuneRequest();
|
||||
|
||||
inline void sendCommon(MidiType inType, unsigned = 0);
|
||||
|
||||
inline void sendClock() { sendRealTime(Clock); };
|
||||
inline void sendStart() { sendRealTime(Start); };
|
||||
inline void sendStop() { sendRealTime(Stop); };
|
||||
inline void sendTick() { sendRealTime(Tick); };
|
||||
inline void sendContinue() { sendRealTime(Continue); };
|
||||
inline void sendActiveSensing() { sendRealTime(ActiveSensing); };
|
||||
inline void sendSystemReset() { sendRealTime(SystemReset); };
|
||||
|
||||
inline void sendRealTime(MidiType inType);
|
||||
|
||||
inline void beginRpn(unsigned inNumber,
|
||||
Channel inChannel);
|
||||
inline void sendRpnValue(unsigned inValue,
|
||||
Channel inChannel);
|
||||
inline void sendRpnValue(byte inMsb,
|
||||
byte inLsb,
|
||||
Channel inChannel);
|
||||
inline void sendRpnIncrement(byte inAmount,
|
||||
Channel inChannel);
|
||||
inline void sendRpnDecrement(byte inAmount,
|
||||
Channel inChannel);
|
||||
inline void endRpn(Channel inChannel);
|
||||
|
||||
inline void beginNrpn(unsigned inNumber,
|
||||
Channel inChannel);
|
||||
inline void sendNrpnValue(unsigned inValue,
|
||||
Channel inChannel);
|
||||
inline void sendNrpnValue(byte inMsb,
|
||||
byte inLsb,
|
||||
Channel inChannel);
|
||||
inline void sendNrpnIncrement(byte inAmount,
|
||||
Channel inChannel);
|
||||
inline void sendNrpnDecrement(byte inAmount,
|
||||
Channel inChannel);
|
||||
inline void endNrpn(Channel inChannel);
|
||||
|
||||
inline void send(const MidiMessage&);
|
||||
|
||||
public:
|
||||
void send(MidiType inType,
|
||||
DataByte inData1,
|
||||
DataByte inData2,
|
||||
Channel inChannel);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// MIDI Input
|
||||
|
||||
public:
|
||||
inline bool read();
|
||||
inline bool read(Channel inChannel);
|
||||
|
||||
public:
|
||||
inline MidiType getType() const;
|
||||
inline Channel getChannel() const;
|
||||
inline DataByte getData1() const;
|
||||
inline DataByte getData2() const;
|
||||
inline const byte* getSysExArray() const;
|
||||
inline unsigned getSysExArrayLength() const;
|
||||
inline bool check() const;
|
||||
|
||||
public:
|
||||
inline Channel getInputChannel() const;
|
||||
inline void setInputChannel(Channel inChannel);
|
||||
|
||||
public:
|
||||
static inline MidiType getTypeFromStatusByte(byte inStatus);
|
||||
static inline Channel getChannelFromStatusByte(byte inStatus);
|
||||
static inline bool isChannelMessage(MidiType inType);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Input Callbacks
|
||||
|
||||
public:
|
||||
inline void setHandleMessage(void (*fptr)(const MidiMessage&)) { mMessageCallback = fptr; };
|
||||
inline void setHandleError(ErrorCallback fptr) { mErrorCallback = fptr; }
|
||||
inline void setHandleNoteOff(NoteOffCallback fptr) { mNoteOffCallback = fptr; }
|
||||
inline void setHandleNoteOn(NoteOnCallback fptr) { mNoteOnCallback = fptr; }
|
||||
inline void setHandleAfterTouchPoly(AfterTouchPolyCallback fptr) { mAfterTouchPolyCallback = fptr; }
|
||||
inline void setHandleControlChange(ControlChangeCallback fptr) { mControlChangeCallback = fptr; }
|
||||
inline void setHandleProgramChange(ProgramChangeCallback fptr) { mProgramChangeCallback = fptr; }
|
||||
inline void setHandleAfterTouchChannel(AfterTouchChannelCallback fptr) { mAfterTouchChannelCallback = fptr; }
|
||||
inline void setHandlePitchBend(PitchBendCallback fptr) { mPitchBendCallback = fptr; }
|
||||
inline void setHandleSystemExclusive(SystemExclusiveCallback fptr) { mSystemExclusiveCallback = fptr; }
|
||||
inline void setHandleTimeCodeQuarterFrame(TimeCodeQuarterFrameCallback fptr) { mTimeCodeQuarterFrameCallback = fptr; }
|
||||
inline void setHandleSongPosition(SongPositionCallback fptr) { mSongPositionCallback = fptr; }
|
||||
inline void setHandleSongSelect(SongSelectCallback fptr) { mSongSelectCallback = fptr; }
|
||||
inline void setHandleTuneRequest(TuneRequestCallback fptr) { mTuneRequestCallback = fptr; }
|
||||
inline void setHandleClock(ClockCallback fptr) { mClockCallback = fptr; }
|
||||
inline void setHandleStart(StartCallback fptr) { mStartCallback = fptr; }
|
||||
inline void setHandleTick(TickCallback fptr) { mTickCallback = fptr; }
|
||||
inline void setHandleContinue(ContinueCallback fptr) { mContinueCallback = fptr; }
|
||||
inline void setHandleStop(StopCallback fptr) { mStopCallback = fptr; }
|
||||
inline void setHandleActiveSensing(ActiveSensingCallback fptr) { mActiveSensingCallback = fptr; }
|
||||
inline void setHandleSystemReset(SystemResetCallback fptr) { mSystemResetCallback = fptr; }
|
||||
|
||||
inline void disconnectCallbackFromType(MidiType inType);
|
||||
|
||||
private:
|
||||
void launchCallback();
|
||||
|
||||
void (*mMessageCallback)(const MidiMessage& message) = nullptr;
|
||||
ErrorCallback mErrorCallback = nullptr;
|
||||
NoteOffCallback mNoteOffCallback = nullptr;
|
||||
NoteOnCallback mNoteOnCallback = nullptr;
|
||||
AfterTouchPolyCallback mAfterTouchPolyCallback = nullptr;
|
||||
ControlChangeCallback mControlChangeCallback = nullptr;
|
||||
ProgramChangeCallback mProgramChangeCallback = nullptr;
|
||||
AfterTouchChannelCallback mAfterTouchChannelCallback = nullptr;
|
||||
PitchBendCallback mPitchBendCallback = nullptr;
|
||||
SystemExclusiveCallback mSystemExclusiveCallback = nullptr;
|
||||
TimeCodeQuarterFrameCallback mTimeCodeQuarterFrameCallback = nullptr;
|
||||
SongPositionCallback mSongPositionCallback = nullptr;
|
||||
SongSelectCallback mSongSelectCallback = nullptr;
|
||||
TuneRequestCallback mTuneRequestCallback = nullptr;
|
||||
ClockCallback mClockCallback = nullptr;
|
||||
StartCallback mStartCallback = nullptr;
|
||||
TickCallback mTickCallback = nullptr;
|
||||
ContinueCallback mContinueCallback = nullptr;
|
||||
StopCallback mStopCallback = nullptr;
|
||||
ActiveSensingCallback mActiveSensingCallback = nullptr;
|
||||
SystemResetCallback mSystemResetCallback = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// MIDI Soft Thru
|
||||
|
||||
public:
|
||||
inline Thru::Mode getFilterMode() const;
|
||||
inline bool getThruState() const;
|
||||
|
||||
inline void turnThruOn(Thru::Mode inThruFilterMode = Thru::Full);
|
||||
inline void turnThruOff();
|
||||
inline void setThruFilterMode(Thru::Mode inThruFilterMode);
|
||||
|
||||
private:
|
||||
void thruFilter(byte inChannel);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// MIDI Parsing
|
||||
|
||||
private:
|
||||
bool parse();
|
||||
inline void handleNullVelocityNoteOnAsNoteOff();
|
||||
inline bool inputFilter(Channel inChannel);
|
||||
inline void resetInput();
|
||||
inline void UpdateLastSentTime();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Transport
|
||||
|
||||
public:
|
||||
Transport* getTransport() { return &mTransport; };
|
||||
|
||||
private:
|
||||
Transport& mTransport;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Internal variables
|
||||
|
||||
private:
|
||||
Channel mInputChannel;
|
||||
StatusByte mRunningStatus_RX;
|
||||
StatusByte mRunningStatus_TX;
|
||||
byte mPendingMessage[3];
|
||||
unsigned mPendingMessageExpectedLength;
|
||||
unsigned mPendingMessageIndex;
|
||||
unsigned mCurrentRpnNumber;
|
||||
unsigned mCurrentNrpnNumber;
|
||||
bool mThruActivated : 1;
|
||||
Thru::Mode mThruFilterMode : 7;
|
||||
MidiMessage mMessage;
|
||||
unsigned long mLastMessageSentTime;
|
||||
unsigned long mLastMessageReceivedTime;
|
||||
unsigned long mSenderActiveSensingPeriodicity;
|
||||
bool mReceiverActiveSensingActivated;
|
||||
int8_t mLastError;
|
||||
|
||||
private:
|
||||
inline StatusByte getStatus(MidiType inType,
|
||||
Channel inChannel) const;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
unsigned encodeSysEx(const byte* inData,
|
||||
byte* outSysEx,
|
||||
unsigned inLength,
|
||||
bool inFlipHeaderBits = false);
|
||||
unsigned decodeSysEx(const byte* inSysEx,
|
||||
byte* outData,
|
||||
unsigned inLength,
|
||||
bool inFlipHeaderBits = false);
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
|
||||
#include "MIDI.hpp"
|
||||
1485
trunk/Arduino/libraries/MIDI_Library/src/MIDI.hpp
Normal file
1485
trunk/Arduino/libraries/MIDI_Library/src/MIDI.hpp
Normal file
File diff suppressed because it is too large
Load Diff
232
trunk/Arduino/libraries/MIDI_Library/src/midi_Defs.h
Normal file
232
trunk/Arduino/libraries/MIDI_Library/src/midi_Defs.h
Normal file
@@ -0,0 +1,232 @@
|
||||
/*!
|
||||
* @file midi_Defs.h
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino - Definitions
|
||||
* @author Francois Best, lathoub
|
||||
* @date 24/02/11
|
||||
* @license MIT - Copyright (c) 2015 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "midi_Namespace.h"
|
||||
|
||||
#if ARDUINO
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
typedef uint8_t byte;
|
||||
#endif
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define MIDI_CHANNEL_OMNI 0
|
||||
#define MIDI_CHANNEL_OFF 17 // and over
|
||||
|
||||
#define MIDI_PITCHBEND_MIN -8192
|
||||
#define MIDI_PITCHBEND_MAX 8191
|
||||
|
||||
/*! Receiving Active Sensing
|
||||
*/
|
||||
static const uint16_t ActiveSensingTimeout = 300;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Type definitions
|
||||
|
||||
typedef byte StatusByte;
|
||||
typedef byte DataByte;
|
||||
typedef byte Channel;
|
||||
typedef byte FilterMode;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Errors
|
||||
static const uint8_t ErrorParse = 0;
|
||||
static const uint8_t ErrorActiveSensingTimeout = 1;
|
||||
static const uint8_t WarningSplitSysEx = 2;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Aliasing
|
||||
|
||||
using ErrorCallback = void (*)(int8_t);
|
||||
using NoteOffCallback = void (*)(Channel channel, byte note, byte velocity);
|
||||
using NoteOnCallback = void (*)(Channel channel, byte note, byte velocity);
|
||||
using AfterTouchPolyCallback = void (*)(Channel channel, byte note, byte velocity);
|
||||
using ControlChangeCallback = void (*)(Channel channel, byte, byte);
|
||||
using ProgramChangeCallback = void (*)(Channel channel, byte);
|
||||
using AfterTouchChannelCallback = void (*)(Channel channel, byte);
|
||||
using PitchBendCallback = void (*)(Channel channel, int);
|
||||
using SystemExclusiveCallback = void (*)(byte * array, unsigned size);
|
||||
using TimeCodeQuarterFrameCallback = void (*)(byte data);
|
||||
using SongPositionCallback = void (*)(unsigned beats);
|
||||
using SongSelectCallback = void (*)(byte songnumber);
|
||||
using TuneRequestCallback = void (*)(void);
|
||||
using ClockCallback = void (*)(void);
|
||||
using StartCallback = void (*)(void);
|
||||
using TickCallback = void (*)(void);
|
||||
using ContinueCallback = void (*)(void);
|
||||
using StopCallback = void (*)(void);
|
||||
using ActiveSensingCallback = void (*)(void);
|
||||
using SystemResetCallback = void (*)(void);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/*! Enumeration of MIDI types */
|
||||
enum MidiType: uint8_t
|
||||
{
|
||||
InvalidType = 0x00, ///< For notifying errors
|
||||
NoteOff = 0x80, ///< Channel Message - Note Off
|
||||
NoteOn = 0x90, ///< Channel Message - Note On
|
||||
AfterTouchPoly = 0xA0, ///< Channel Message - Polyphonic AfterTouch
|
||||
ControlChange = 0xB0, ///< Channel Message - Control Change / Channel Mode
|
||||
ProgramChange = 0xC0, ///< Channel Message - Program Change
|
||||
AfterTouchChannel = 0xD0, ///< Channel Message - Channel (monophonic) AfterTouch
|
||||
PitchBend = 0xE0, ///< Channel Message - Pitch Bend
|
||||
SystemExclusive = 0xF0, ///< System Exclusive
|
||||
SystemExclusiveStart = SystemExclusive, ///< System Exclusive Start
|
||||
TimeCodeQuarterFrame = 0xF1, ///< System Common - MIDI Time Code Quarter Frame
|
||||
SongPosition = 0xF2, ///< System Common - Song Position Pointer
|
||||
SongSelect = 0xF3, ///< System Common - Song Select
|
||||
Undefined_F4 = 0xF4,
|
||||
Undefined_F5 = 0xF5,
|
||||
TuneRequest = 0xF6, ///< System Common - Tune Request
|
||||
SystemExclusiveEnd = 0xF7, ///< System Exclusive End
|
||||
Clock = 0xF8, ///< System Real Time - Timing Clock
|
||||
Undefined_F9 = 0xF9,
|
||||
Tick = Undefined_F9, ///< System Real Time - Timing Tick (1 tick = 10 milliseconds)
|
||||
Start = 0xFA, ///< System Real Time - Start
|
||||
Continue = 0xFB, ///< System Real Time - Continue
|
||||
Stop = 0xFC, ///< System Real Time - Stop
|
||||
Undefined_FD = 0xFD,
|
||||
ActiveSensing = 0xFE, ///< System Real Time - Active Sensing
|
||||
SystemReset = 0xFF, ///< System Real Time - System Reset
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/*! Enumeration of Thru filter modes */
|
||||
struct Thru
|
||||
{
|
||||
enum Mode
|
||||
{
|
||||
Off = 0, ///< Thru disabled (nothing passes through).
|
||||
Full = 1, ///< Fully enabled Thru (every incoming message is sent back).
|
||||
SameChannel = 2, ///< Only the messages on the Input Channel will be sent back.
|
||||
DifferentChannel = 3, ///< All the messages but the ones on the Input Channel will be sent back.
|
||||
};
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Enumeration of Control Change command numbers.
|
||||
See the detailed controllers numbers & description here:
|
||||
http://www.somascape.org/midi/tech/spec.html#ctrlnums
|
||||
*/
|
||||
enum MidiControlChangeNumber: uint8_t
|
||||
{
|
||||
// High resolution Continuous Controllers MSB (+32 for LSB) ----------------
|
||||
BankSelect = 0,
|
||||
ModulationWheel = 1,
|
||||
BreathController = 2,
|
||||
// CC3 undefined
|
||||
FootController = 4,
|
||||
PortamentoTime = 5,
|
||||
DataEntryMSB = 6,
|
||||
ChannelVolume = 7,
|
||||
Balance = 8,
|
||||
// CC9 undefined
|
||||
Pan = 10,
|
||||
ExpressionController = 11,
|
||||
EffectControl1 = 12,
|
||||
EffectControl2 = 13,
|
||||
// CC14 undefined
|
||||
// CC15 undefined
|
||||
GeneralPurposeController1 = 16,
|
||||
GeneralPurposeController2 = 17,
|
||||
GeneralPurposeController3 = 18,
|
||||
GeneralPurposeController4 = 19,
|
||||
|
||||
DataEntryLSB = 38,
|
||||
|
||||
// Switches ----------------------------------------------------------------
|
||||
Sustain = 64,
|
||||
Portamento = 65,
|
||||
Sostenuto = 66,
|
||||
SoftPedal = 67,
|
||||
Legato = 68,
|
||||
Hold = 69,
|
||||
|
||||
// Low resolution continuous controllers -----------------------------------
|
||||
SoundController1 = 70, ///< Synth: Sound Variation FX: Exciter On/Off
|
||||
SoundController2 = 71, ///< Synth: Harmonic Content FX: Compressor On/Off
|
||||
SoundController3 = 72, ///< Synth: Release Time FX: Distortion On/Off
|
||||
SoundController4 = 73, ///< Synth: Attack Time FX: EQ On/Off
|
||||
SoundController5 = 74, ///< Synth: Brightness FX: Expander On/Off
|
||||
SoundController6 = 75, ///< Synth: Decay Time FX: Reverb On/Off
|
||||
SoundController7 = 76, ///< Synth: Vibrato Rate FX: Delay On/Off
|
||||
SoundController8 = 77, ///< Synth: Vibrato Depth FX: Pitch Transpose On/Off
|
||||
SoundController9 = 78, ///< Synth: Vibrato Delay FX: Flange/Chorus On/Off
|
||||
SoundController10 = 79, ///< Synth: Undefined FX: Special Effects On/Off
|
||||
GeneralPurposeController5 = 80,
|
||||
GeneralPurposeController6 = 81,
|
||||
GeneralPurposeController7 = 82,
|
||||
GeneralPurposeController8 = 83,
|
||||
PortamentoControl = 84,
|
||||
// CC85 to CC90 undefined
|
||||
Effects1 = 91, ///< Reverb send level
|
||||
Effects2 = 92, ///< Tremolo depth
|
||||
Effects3 = 93, ///< Chorus send level
|
||||
Effects4 = 94, ///< Celeste depth
|
||||
Effects5 = 95, ///< Phaser depth
|
||||
DataIncrement = 96,
|
||||
DataDecrement = 97,
|
||||
NRPNLSB = 98, ///< Non-Registered Parameter Number (LSB)
|
||||
NRPNMSB = 99, ///< Non-Registered Parameter Number (MSB)
|
||||
RPNLSB = 100, ///< Registered Parameter Number (LSB)
|
||||
RPNMSB = 101, ///< Registered Parameter Number (MSB)
|
||||
|
||||
// Channel Mode messages ---------------------------------------------------
|
||||
AllSoundOff = 120,
|
||||
ResetAllControllers = 121,
|
||||
LocalControl = 122,
|
||||
AllNotesOff = 123,
|
||||
OmniModeOff = 124,
|
||||
OmniModeOn = 125,
|
||||
MonoModeOn = 126,
|
||||
PolyModeOn = 127
|
||||
};
|
||||
|
||||
struct RPN
|
||||
{
|
||||
enum RegisteredParameterNumbers: uint16_t
|
||||
{
|
||||
PitchBendSensitivity = 0x0000,
|
||||
ChannelFineTuning = 0x0001,
|
||||
ChannelCoarseTuning = 0x0002,
|
||||
SelectTuningProgram = 0x0003,
|
||||
SelectTuningBank = 0x0004,
|
||||
ModulationDepthRange = 0x0005,
|
||||
NullFunction = (0x7f << 7) + 0x7f,
|
||||
};
|
||||
};
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
105
trunk/Arduino/libraries/MIDI_Library/src/midi_Message.h
Normal file
105
trunk/Arduino/libraries/MIDI_Library/src/midi_Message.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*!
|
||||
* @file midi_Message.h
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino - Message struct definition
|
||||
* @author Francois Best
|
||||
* @date 11/06/14
|
||||
* @license MIT - Copyright (c) 2015 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "midi_Namespace.h"
|
||||
#include "midi_Defs.h"
|
||||
#ifndef ARDUINO
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
/*! The Message structure contains decoded data of a MIDI message
|
||||
read from the serial port with read()
|
||||
*/
|
||||
template<unsigned SysExMaxSize>
|
||||
struct Message
|
||||
{
|
||||
/*! Default constructor
|
||||
\n Initializes the attributes with their default values.
|
||||
*/
|
||||
inline Message()
|
||||
: channel(0)
|
||||
, type(MIDI_NAMESPACE::InvalidType)
|
||||
, data1(0)
|
||||
, data2(0)
|
||||
, valid(false)
|
||||
{
|
||||
memset(sysexArray, 0, sSysExMaxSize * sizeof(DataByte));
|
||||
}
|
||||
|
||||
/*! The maximum size for the System Exclusive array.
|
||||
*/
|
||||
static const unsigned sSysExMaxSize = SysExMaxSize;
|
||||
|
||||
/*! The MIDI channel on which the message was recieved.
|
||||
\n Value goes from 1 to 16.
|
||||
*/
|
||||
Channel channel;
|
||||
|
||||
/*! The type of the message
|
||||
(see the MidiType enum for types reference)
|
||||
*/
|
||||
MidiType type;
|
||||
|
||||
/*! The first data byte.
|
||||
\n Value goes from 0 to 127.
|
||||
*/
|
||||
DataByte data1;
|
||||
|
||||
/*! The second data byte.
|
||||
If the message is only 2 bytes long, this one is null.
|
||||
\n Value goes from 0 to 127.
|
||||
*/
|
||||
DataByte data2;
|
||||
|
||||
/*! System Exclusive dedicated byte array.
|
||||
\n Array length is stocked on 16 bits,
|
||||
in data1 (LSB) and data2 (MSB)
|
||||
*/
|
||||
DataByte sysexArray[sSysExMaxSize];
|
||||
|
||||
/*! This boolean indicates if the message is valid or not.
|
||||
There is no channel consideration here,
|
||||
validity means the message respects the MIDI norm.
|
||||
*/
|
||||
bool valid;
|
||||
|
||||
/*! Total Length of the message.
|
||||
*/
|
||||
unsigned length;
|
||||
|
||||
inline unsigned getSysExSize() const
|
||||
{
|
||||
const unsigned size = unsigned(data2) << 8 | data1;
|
||||
return size > sSysExMaxSize ? sSysExMaxSize : size;
|
||||
}
|
||||
};
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
38
trunk/Arduino/libraries/MIDI_Library/src/midi_Namespace.h
Normal file
38
trunk/Arduino/libraries/MIDI_Library/src/midi_Namespace.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*!
|
||||
* @file midi_Namespace.h
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino - Namespace declaration
|
||||
* @author Francois Best
|
||||
* @date 24/02/11
|
||||
* @license MIT - Copyright (c) 2015 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MIDI_NAMESPACE midi
|
||||
#define BEGIN_MIDI_NAMESPACE namespace MIDI_NAMESPACE {
|
||||
#define END_MIDI_NAMESPACE }
|
||||
|
||||
#define USING_NAMESPACE_MIDI using namespace MIDI_NAMESPACE;
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
51
trunk/Arduino/libraries/MIDI_Library/src/midi_Platform.h
Normal file
51
trunk/Arduino/libraries/MIDI_Library/src/midi_Platform.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*!
|
||||
* @file midi_Platform.h
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino - Platform
|
||||
* @license MIT - Copyright (c) 2015 Francois Best
|
||||
* @author lathoub
|
||||
* @date 22/03/20
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "midi_Defs.h"
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
#if ARDUINO
|
||||
|
||||
// DefaultPlatform is the Arduino Platform
|
||||
struct DefaultPlatform
|
||||
{
|
||||
static unsigned long now() { return ::millis(); };
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
struct DefaultPlatform
|
||||
{
|
||||
static unsigned long now() { return 0; };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
62
trunk/Arduino/libraries/MIDI_Library/src/midi_RingBuffer.h
Normal file
62
trunk/Arduino/libraries/MIDI_Library/src/midi_RingBuffer.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*!
|
||||
* @file midi_RingBuffer.h
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for Arduino - Ring Buffer
|
||||
* @author Francois Best
|
||||
* @date 10/10/2016
|
||||
* @license MIT - Copyright (c) 2016 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "midi_Namespace.h"
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
template<typename DataType, int Size>
|
||||
class RingBuffer
|
||||
{
|
||||
public:
|
||||
RingBuffer();
|
||||
~RingBuffer();
|
||||
|
||||
public:
|
||||
int getLength() const;
|
||||
bool isEmpty() const;
|
||||
|
||||
public:
|
||||
void write(DataType inData);
|
||||
void write(const DataType* inData, int inSize);
|
||||
void clear();
|
||||
|
||||
public:
|
||||
DataType read();
|
||||
void read(DataType* outData, int inSize);
|
||||
|
||||
private:
|
||||
DataType mData[Size];
|
||||
DataType* mWriteHead;
|
||||
DataType* mReadHead;
|
||||
};
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
|
||||
#include "midi_RingBuffer.hpp"
|
||||
121
trunk/Arduino/libraries/MIDI_Library/src/midi_RingBuffer.hpp
Normal file
121
trunk/Arduino/libraries/MIDI_Library/src/midi_RingBuffer.hpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/*!
|
||||
* @file midi_RingBuffer.hpp
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for Arduino - Ring Buffer
|
||||
* @author Francois Best
|
||||
* @date 10/10/2016
|
||||
* @license MIT - Copyright (c) 2016 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
template<typename DataType, int Size>
|
||||
RingBuffer<DataType, Size>::RingBuffer()
|
||||
: mWriteHead(mData)
|
||||
, mReadHead(mData)
|
||||
{
|
||||
memset(mData, DataType(0), Size * sizeof(DataType));
|
||||
}
|
||||
|
||||
template<typename DataType, int Size>
|
||||
RingBuffer<DataType, Size>::~RingBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename DataType, int Size>
|
||||
int RingBuffer<DataType, Size>::getLength() const
|
||||
{
|
||||
if (mReadHead == mWriteHead)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (mWriteHead > mReadHead)
|
||||
{
|
||||
return int(mWriteHead - mReadHead);
|
||||
}
|
||||
else
|
||||
{
|
||||
return int(mWriteHead - mData) + Size - int(mReadHead - mData);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename DataType, int Size>
|
||||
bool RingBuffer<DataType, Size>::isEmpty() const
|
||||
{
|
||||
return mReadHead == mWriteHead;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename DataType, int Size>
|
||||
void RingBuffer<DataType, Size>::write(DataType inData)
|
||||
{
|
||||
*mWriteHead++ = inData;
|
||||
if (mWriteHead >= mData + Size)
|
||||
{
|
||||
mWriteHead = mData;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename DataType, int Size>
|
||||
void RingBuffer<DataType, Size>::write(const DataType* inData, int inSize)
|
||||
{
|
||||
for (int i = 0; i < inSize; ++i)
|
||||
{
|
||||
write(inData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename DataType, int Size>
|
||||
void RingBuffer<DataType, Size>::clear()
|
||||
{
|
||||
memset(mData, DataType(0), Size * sizeof(DataType));
|
||||
mReadHead = mData;
|
||||
mWriteHead = mData;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename DataType, int Size>
|
||||
DataType RingBuffer<DataType, Size>::read()
|
||||
{
|
||||
const DataType data = *mReadHead++;
|
||||
if (mReadHead >= mData + Size)
|
||||
{
|
||||
mReadHead = mData;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
template<typename DataType, int Size>
|
||||
void RingBuffer<DataType, Size>::read(DataType* outData, int inSize)
|
||||
{
|
||||
for (int i = 0; i < inSize; ++i)
|
||||
{
|
||||
outData[i] = read();
|
||||
}
|
||||
}
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
104
trunk/Arduino/libraries/MIDI_Library/src/midi_Settings.h
Normal file
104
trunk/Arduino/libraries/MIDI_Library/src/midi_Settings.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*!
|
||||
* @file midi_Settings.h
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino - Settings
|
||||
* @author Francois Best
|
||||
* @date 24/02/11
|
||||
* @license MIT - Copyright (c) 2015 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "midi_Defs.h"
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
/*! \brief Default Settings for the MIDI Library.
|
||||
|
||||
To change the default settings, don't edit them there, create a subclass and
|
||||
override the values in that subclass, then use the MIDI_CREATE_CUSTOM_INSTANCE
|
||||
macro to create your instance. The settings you don't override will keep their
|
||||
default value. Eg:
|
||||
\code{.cpp}
|
||||
struct MySettings : public midi::DefaultSettings
|
||||
{
|
||||
static const unsigned SysExMaxSize = 1024; // Accept SysEx messages up to 1024 bytes long.
|
||||
};
|
||||
|
||||
MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial2, midi, MySettings);
|
||||
\endcode
|
||||
*/
|
||||
struct DefaultSettings
|
||||
{
|
||||
/*! Running status enables short messages when sending multiple values
|
||||
of the same type and channel.\n
|
||||
Must be disabled to send USB MIDI messages to a computer
|
||||
Warning: does not work with some hardware, enable with caution.
|
||||
*/
|
||||
static const bool UseRunningStatus = false;
|
||||
|
||||
/*! NoteOn with 0 velocity should be handled as NoteOf.\n
|
||||
Set to true to get NoteOff events when receiving null-velocity NoteOn messages.\n
|
||||
Set to false to get NoteOn events when receiving null-velocity NoteOn messages.
|
||||
*/
|
||||
static const bool HandleNullVelocityNoteOnAsNoteOff = true;
|
||||
|
||||
/*! Setting this to true will make MIDI.read parse only one byte of data for each
|
||||
call when data is available. This can speed up your application if receiving
|
||||
a lot of traffic, but might induce MIDI Thru and treatment latency.
|
||||
*/
|
||||
static const bool Use1ByteParsing = true;
|
||||
|
||||
/*! Maximum size of SysEx receivable. Decrease to save RAM if you don't expect
|
||||
to receive SysEx, or adjust accordingly.
|
||||
*/
|
||||
static const unsigned SysExMaxSize = 128;
|
||||
|
||||
/*! Global switch to turn on/off sender ActiveSensing
|
||||
Set to true to send ActiveSensing
|
||||
Set to false will not send ActiveSensing message (will also save memory)
|
||||
*/
|
||||
static const bool UseSenderActiveSensing = false;
|
||||
|
||||
/*! Global switch to turn on/off receiver ActiveSensing
|
||||
Set to true to check for message timeouts (via ErrorCallback)
|
||||
Set to false will not check if chained device are still alive (if they use ActiveSensing) (will also save memory)
|
||||
*/
|
||||
static const bool UseReceiverActiveSensing = false;
|
||||
|
||||
/*! Active Sensing is intended to be sent
|
||||
repeatedly by the sender to tell the receiver that a connection is alive. Use
|
||||
of this message is optional. When initially received, the
|
||||
receiver will expect to receive another Active Sensing
|
||||
message each 300ms (max), and if it does not then it will
|
||||
assume that the connection has been terminated. At
|
||||
termination, the receiver will turn off all voices and return to
|
||||
normal (non- active sensing) operation.
|
||||
|
||||
Typical value is 250 (ms) - an Active Sensing command is send every 250ms.
|
||||
(All Roland devices send Active Sensing every 250ms)
|
||||
|
||||
Setting this field to 0 will disable sending MIDI active sensing.
|
||||
*/
|
||||
static const uint16_t SenderActiveSensingPeriodicity = 0;
|
||||
};
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
144
trunk/Arduino/libraries/MIDI_Library/src/midi_UsbDefs.h
Normal file
144
trunk/Arduino/libraries/MIDI_Library/src/midi_UsbDefs.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*!
|
||||
* @file midi_UsbDefs.h
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino - Definitions
|
||||
* @author Francois Best
|
||||
* @date 24/02/11
|
||||
* @license MIT - Copyright (c) 2016 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "midi_Defs.h"
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
struct CodeIndexNumbers
|
||||
{
|
||||
enum
|
||||
{
|
||||
reserved = 0x00,
|
||||
misc = reserved,
|
||||
|
||||
cableEvent = 0x01,
|
||||
systemCommon2Bytes = 0x02,
|
||||
systemCommon3Bytes = 0x03,
|
||||
|
||||
sysExStart = 0x04,
|
||||
sysExContinue = sysExStart,
|
||||
|
||||
systemCommon1Byte = 0x05,
|
||||
sysExEnds1Byte = systemCommon1Byte,
|
||||
|
||||
sysExEnds2Bytes = 0x06,
|
||||
sysExEnds3Bytes = 0x07,
|
||||
noteOff = 0x08,
|
||||
noteOn = 0x09,
|
||||
polyPressure = 0x0A,
|
||||
controlChange = 0x0B,
|
||||
programChange = 0x0C,
|
||||
channelPressure = 0x0D,
|
||||
pitchBend = 0x0E,
|
||||
singleByte = 0x0F,
|
||||
};
|
||||
|
||||
static inline byte getSize(byte inCodeIndexNumber)
|
||||
{
|
||||
switch (inCodeIndexNumber)
|
||||
{
|
||||
case noteOn:
|
||||
case noteOff:
|
||||
case controlChange:
|
||||
case pitchBend:
|
||||
case polyPressure:
|
||||
case systemCommon3Bytes:
|
||||
case sysExEnds3Bytes:
|
||||
case sysExStart:
|
||||
return 3;
|
||||
|
||||
case programChange:
|
||||
case channelPressure:
|
||||
case systemCommon2Bytes:
|
||||
case sysExEnds2Bytes:
|
||||
return 2;
|
||||
|
||||
case systemCommon1Byte:
|
||||
case singleByte:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0; // Can be any length (1, 2 or 3).
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct UsbMidiEventPacket
|
||||
{
|
||||
public:
|
||||
inline UsbMidiEventPacket()
|
||||
{
|
||||
memset(mData, 0, 4 * sizeof(byte));
|
||||
}
|
||||
|
||||
public:
|
||||
inline void setHeader(byte inCableNumber, byte inCodeIndexNumber)
|
||||
{
|
||||
const byte msb = (0x0f & inCableNumber) << 4;
|
||||
const byte lsb = (0x0f & inCodeIndexNumber);
|
||||
mData[0] = msb | lsb;
|
||||
}
|
||||
inline void setMidiData(const byte* inData)
|
||||
{
|
||||
mData[1] = *inData++;
|
||||
mData[2] = *inData++;
|
||||
mData[3] = *inData;
|
||||
}
|
||||
inline byte getCableNumber() const
|
||||
{
|
||||
return mData[0] >> 4;
|
||||
}
|
||||
inline byte getCodeIndexNumber() const
|
||||
{
|
||||
return mData[0] & 0x0f;
|
||||
}
|
||||
inline const byte* getMidiData() const
|
||||
{
|
||||
return mData + 1;
|
||||
}
|
||||
inline byte* getMidiData()
|
||||
{
|
||||
return mData + 1;
|
||||
}
|
||||
inline UsbMidiEventPacket& operator=(const byte* inData)
|
||||
{
|
||||
mData[0] = *inData++;
|
||||
setMidiData(inData);
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
byte mData[4];
|
||||
};
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
72
trunk/Arduino/libraries/MIDI_Library/src/midi_UsbTransport.h
Normal file
72
trunk/Arduino/libraries/MIDI_Library/src/midi_UsbTransport.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*!
|
||||
* @file midi_UsbTransport.h
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino - Transport layer for USB MIDI
|
||||
* @author Francois Best
|
||||
* @date 10/10/2016
|
||||
* @license MIT - Copyright (c) 2016 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "midi_Defs.h"
|
||||
#include "midi_RingBuffer.h"
|
||||
#include <MIDIUSB.h>
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
template<unsigned BuffersSize>
|
||||
class UsbTransport
|
||||
{
|
||||
public:
|
||||
inline UsbTransport();
|
||||
inline ~UsbTransport();
|
||||
|
||||
public: // Serial / Stream API required for template compatibility
|
||||
inline void begin(unsigned inBaudrate);
|
||||
inline unsigned available();
|
||||
inline byte read();
|
||||
inline void write(byte inData);
|
||||
|
||||
private:
|
||||
inline bool pollUsbMidi();
|
||||
inline void recomposeAndSendTxPackets();
|
||||
inline void resetTx();
|
||||
static inline byte encodePacketHeader(StatusByte inStatusByte);
|
||||
static inline int getPacketLength(const midiEventPacket_t& inPacket);
|
||||
|
||||
private:
|
||||
typedef RingBuffer<byte, BuffersSize> Buffer;
|
||||
Buffer mTxBuffer;
|
||||
Buffer mRxBuffer;
|
||||
|
||||
union TxPacket
|
||||
{
|
||||
byte mDataArray[4];
|
||||
midiEventPacket_t mPacket;
|
||||
};
|
||||
TxPacket mCurrentTxPacket;
|
||||
int mCurrentTxPacketByteIndex;
|
||||
};
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
|
||||
#include "midi_UsbTransport.hpp"
|
||||
180
trunk/Arduino/libraries/MIDI_Library/src/midi_UsbTransport.hpp
Normal file
180
trunk/Arduino/libraries/MIDI_Library/src/midi_UsbTransport.hpp
Normal file
@@ -0,0 +1,180 @@
|
||||
/*!
|
||||
* @file midi_UsbTransport.hpp
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino - Transport layer for USB MIDI
|
||||
* @author Francois Best
|
||||
* @date 10/10/2016
|
||||
* @license MIT - Copyright (c) 2016 Francois Best
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline UsbTransport<BufferSize>::UsbTransport()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline UsbTransport<BufferSize>::~UsbTransport()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline void UsbTransport<BufferSize>::begin(unsigned inBaudrate)
|
||||
{
|
||||
mTxBuffer.clear();
|
||||
mRxBuffer.clear();
|
||||
}
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline unsigned UsbTransport<BufferSize>::available()
|
||||
{
|
||||
pollUsbMidi();
|
||||
return mRxBuffer.getLength();
|
||||
}
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline byte UsbTransport<BufferSize>::read()
|
||||
{
|
||||
return mRxBuffer.read();
|
||||
}
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline void UsbTransport<BufferSize>::write(byte inData)
|
||||
{
|
||||
mTxBuffer.write(inData);
|
||||
recomposeAndSendTxPackets();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline bool UsbTransport<BufferSize>::pollUsbMidi()
|
||||
{
|
||||
bool received = false;
|
||||
midiEventPacket_t packet = MidiUSB.read();
|
||||
while (packet.header != 0)
|
||||
{
|
||||
received = true;
|
||||
|
||||
switch (packet.header << 4)
|
||||
{
|
||||
// 3 bytes messages
|
||||
case midi::NoteOff:
|
||||
case midi::NoteOn:
|
||||
case midi::AfterTouchPoly:
|
||||
case midi::ControlChange:
|
||||
case midi::PitchBend:
|
||||
mRxBuffer.write(packet.byte1);
|
||||
mRxBuffer.write(packet.byte2);
|
||||
mRxBuffer.write(packet.byte3);
|
||||
break;
|
||||
|
||||
// 2 bytes messages
|
||||
case midi::ProgramChange:
|
||||
case midi::AfterTouchChannel:
|
||||
mRxBuffer.write(packet.byte1);
|
||||
mRxBuffer.write(packet.byte2);
|
||||
break;
|
||||
|
||||
// 1 byte message
|
||||
case midi::TuneRequest:
|
||||
case midi::Clock:
|
||||
case midi::Start:
|
||||
case midi::Continue:
|
||||
case midi::Stop:
|
||||
case midi::ActiveSensing:
|
||||
case midi::SystemReset:
|
||||
mRxBuffer.write(packet.byte1);
|
||||
break;
|
||||
|
||||
// Special cases
|
||||
// case midi::SystemExclusive:
|
||||
// case midi::TimeCodeQuarterFrame:
|
||||
// case midi::SongPosition:
|
||||
// case midi::SongSelect:
|
||||
// break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
packet = MidiUSB.read();
|
||||
}
|
||||
return received;
|
||||
}
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline void UsbTransport<BufferSize>::recomposeAndSendTxPackets()
|
||||
{
|
||||
while (!mTxBuffer.isEmpty())
|
||||
{
|
||||
const byte data = mTxBuffer.read();
|
||||
if (mCurrentTxPacketByteIndex == 0)
|
||||
{
|
||||
mCurrentTxPacket.mPacket.header = encodePacketHeader(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentTxPacket.mDataArray[mCurrentTxPacketByteIndex] = data;
|
||||
}
|
||||
mCurrentTxPacketByteIndex++;
|
||||
|
||||
const int packetLength = getPacketLength(mCurrentTxPacket.mPacket);
|
||||
|
||||
if (mCurrentTxPacketByteIndex == packetLength)
|
||||
{
|
||||
MidiUSB.write(mCurrentTxPacket.mDataArray, packetLength);
|
||||
resetTx();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline void UsbTransport<BufferSize>::resetTx()
|
||||
{
|
||||
mCurrentTxPacket.mPacket.header = 0;
|
||||
mCurrentTxPacket.mPacket.byte1 = 0;
|
||||
mCurrentTxPacket.mPacket.byte2 = 0;
|
||||
mCurrentTxPacket.mPacket.byte3 = 0;
|
||||
mCurrentTxPacketByteIndex = 0;
|
||||
}
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline byte UsbTransport<BufferSize>::encodePacketHeader(StatusByte inStatusByte)
|
||||
{
|
||||
// todo: fix me for other types than channel
|
||||
return inStatusByte >> 4;
|
||||
}
|
||||
|
||||
template<unsigned BufferSize>
|
||||
inline int UsbTransport<BufferSize>::getPacketLength(const midiEventPacket_t& inPacket)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
125
trunk/Arduino/libraries/MIDI_Library/src/serialMIDI.h
Normal file
125
trunk/Arduino/libraries/MIDI_Library/src/serialMIDI.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/*!
|
||||
* @file serialMIDI.h
|
||||
* Project Arduino MIDI Library
|
||||
* @brief MIDI Library for the Arduino - Platform
|
||||
* @license MIT - Copyright (c) 2015 Francois Best
|
||||
* @author lathoub, Francois Best
|
||||
* @date 22/03/20
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "midi_Namespace.h"
|
||||
|
||||
BEGIN_MIDI_NAMESPACE
|
||||
|
||||
struct DefaultSerialSettings
|
||||
{
|
||||
/*! Override the default MIDI baudrate to transmit over USB serial, to
|
||||
a decoding program such as Hairless MIDI (set baudrate to 115200)\n
|
||||
http://projectgus.github.io/hairless-midiserial/
|
||||
*/
|
||||
static const long BaudRate = 31250;
|
||||
};
|
||||
|
||||
template <class SerialPort, class _Settings = DefaultSerialSettings>
|
||||
class SerialMIDI
|
||||
{
|
||||
typedef _Settings Settings;
|
||||
|
||||
public:
|
||||
SerialMIDI(SerialPort& inSerial)
|
||||
: mSerial(inSerial)
|
||||
{
|
||||
};
|
||||
|
||||
public:
|
||||
static const bool thruActivated = true;
|
||||
|
||||
void begin()
|
||||
{
|
||||
// Initialise the Serial port
|
||||
#if defined(AVR_CAKE)
|
||||
mSerial. template open<Settings::BaudRate>();
|
||||
#else
|
||||
mSerial.begin(Settings::BaudRate);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool beginTransmission(MidiType)
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
void write(byte value)
|
||||
{
|
||||
mSerial.write(value);
|
||||
};
|
||||
|
||||
void endTransmission()
|
||||
{
|
||||
};
|
||||
|
||||
byte read()
|
||||
{
|
||||
return mSerial.read();
|
||||
};
|
||||
|
||||
unsigned available()
|
||||
{
|
||||
return mSerial.available();
|
||||
};
|
||||
|
||||
private:
|
||||
SerialPort& mSerial;
|
||||
};
|
||||
|
||||
/*! \brief Create an instance of the library attached to a serial port.
|
||||
You can use HardwareSerial or SoftwareSerial for the serial port.
|
||||
Example: MIDI_CREATE_INSTANCE(HardwareSerial, Serial2, midi2);
|
||||
Then call midi2.begin(), midi2.read() etc..
|
||||
*/
|
||||
#define MIDI_CREATE_INSTANCE(Type, SerialPort, Name) \
|
||||
MIDI_NAMESPACE::SerialMIDI<Type> serial##Name(SerialPort);\
|
||||
MIDI_NAMESPACE::MidiInterface<MIDI_NAMESPACE::SerialMIDI<Type>> Name((MIDI_NAMESPACE::SerialMIDI<Type>&)serial##Name);
|
||||
|
||||
#if defined(ARDUINO_SAM_DUE) || defined(USBCON) || defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__)
|
||||
// Leonardo, Due and other USB boards use Serial1 by default.
|
||||
#define MIDI_CREATE_DEFAULT_INSTANCE() \
|
||||
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
|
||||
#else
|
||||
/*! \brief Create an instance of the library with default name, serial port
|
||||
and settings, for compatibility with sketches written with pre-v4.2 MIDI Lib,
|
||||
or if you don't bother using custom names, serial port or settings.
|
||||
*/
|
||||
#define MIDI_CREATE_DEFAULT_INSTANCE() \
|
||||
MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI);
|
||||
#endif
|
||||
|
||||
/*! \brief Create an instance of the library attached to a serial port with
|
||||
custom settings.
|
||||
@see DefaultSettings
|
||||
@see MIDI_CREATE_INSTANCE
|
||||
*/
|
||||
#define MIDI_CREATE_CUSTOM_INSTANCE(Type, SerialPort, Name, Settings) \
|
||||
MIDI_NAMESPACE::SerialMIDI<Type, Settings> serial##Name(SerialPort);\
|
||||
MIDI_NAMESPACE::MidiInterface<MIDI_NAMESPACE::SerialMIDI<Type, Settings>> Name((MIDI_NAMESPACE::SerialMIDI<Type, Settings>&)serial##Name);
|
||||
|
||||
END_MIDI_NAMESPACE
|
||||
Reference in New Issue
Block a user