diff --git a/src/MIDI.h b/src/MIDI.h index 5575e32..6f21ec6 100644 --- a/src/MIDI.h +++ b/src/MIDI.h @@ -40,7 +40,7 @@ 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 +template class MidiInterface { public: diff --git a/src/MIDI.hpp b/src/MIDI.hpp index 7a154c2..b6df785 100644 --- a/src/MIDI.hpp +++ b/src/MIDI.hpp @@ -26,8 +26,8 @@ BEGIN_MIDI_NAMESPACE /// \brief Constructor for MidiInterface. -template -MidiInterface::MidiInterface(SerialPort& inSerial) +template +inline MidiInterface::MidiInterface(SerialPort& inSerial) : mSerial(inSerial) { #if MIDI_BUILD_INPUT && MIDI_USE_CALLBACKS @@ -56,8 +56,8 @@ MidiInterface::MidiInterface(SerialPort& inSerial) This is not really useful for the Arduino, as it is never called... */ -template -MidiInterface::~MidiInterface() +template +inline MidiInterface::~MidiInterface() { } @@ -69,21 +69,22 @@ MidiInterface::~MidiInterface() - Input channel set to 1 if no value is specified - Full thru mirroring */ -template -void MidiInterface::begin(Channel inChannel) +template +void MidiInterface::begin(Channel inChannel) { // Initialise the Serial port -#if defined(ARDUINO) - mSerial.begin(MIDI_BAUDRATE); -#elif defined(FSE_AVR) - mSerial. template open(); +#if defined(FSE_AVR) + mSerial. template open(); +#else + mSerial.begin(Settings::BaudRate); #endif -#if MIDI_BUILD_OUTPUT && MIDI_USE_RUNNING_STATUS - - mRunningStatus_TX = InvalidType; - -#endif // MIDI_BUILD_OUTPUT && MIDI_USE_RUNNING_STATUS +#if MIDI_BUILD_OUTPUT + if (Settings::UseRunningStatus) + { + mRunningStatus_TX = InvalidType; + } +#endif // MIDI_BUILD_OUTPUT #if MIDI_BUILD_INPUT @@ -133,22 +134,21 @@ void MidiInterface::begin(Channel inChannel) This is an internal method, use it only if you need to send raw data from your code, at your own risks. */ -template -void MidiInterface::send(MidiType inType, - DataByte inData1, - DataByte inData2, - Channel inChannel) +template +void MidiInterface::send(MidiType inType, + DataByte inData1, + DataByte inData2, + Channel inChannel) { // Then test if channel is valid if (inChannel >= MIDI_CHANNEL_OFF || inChannel == MIDI_CHANNEL_OMNI || inType < NoteOff) { - -#if MIDI_USE_RUNNING_STATUS - mRunningStatus_TX = InvalidType; -#endif - + if (Settings::UseRunningStatus) + { + mRunningStatus_TX = InvalidType; + } return; // Don't send anything } @@ -160,18 +160,20 @@ void MidiInterface::send(MidiType inType, const StatusByte status = getStatus(inType, inChannel); -#if MIDI_USE_RUNNING_STATUS - // Check Running Status - if (mRunningStatus_TX != status) + if (Settings::UseRunningStatus) { - // New message, memorise and send header - mRunningStatus_TX = status; - mSerial.write(mRunningStatus_TX); + if (mRunningStatus_TX != status) + { + // New message, memorise and send header + mRunningStatus_TX = status; + mSerial.write(mRunningStatus_TX); + } + } + else + { + // Don't care about running status, send the status byte. + mSerial.write(status); } -#else - // Don't care about running status, send the status byte. - mSerial.write(status); -#endif // Then send data mSerial.write(inData1); @@ -195,10 +197,10 @@ void MidiInterface::send(MidiType inType, Take a look at the values, names and frequencies of notes here: http://www.phys.unsw.edu.au/jw/notes.html */ -template -void MidiInterface::sendNoteOn(DataByte inNoteNumber, - DataByte inVelocity, - Channel inChannel) +template +void MidiInterface::sendNoteOn(DataByte inNoteNumber, + DataByte inVelocity, + Channel inChannel) { send(NoteOn, inNoteNumber, inVelocity, inChannel); } @@ -214,10 +216,10 @@ void MidiInterface::sendNoteOn(DataByte inNoteNumber, Take a look at the values, names and frequencies of notes here: http://www.phys.unsw.edu.au/jw/notes.html */ -template -void MidiInterface::sendNoteOff(DataByte inNoteNumber, - DataByte inVelocity, - Channel inChannel) +template +void MidiInterface::sendNoteOff(DataByte inNoteNumber, + DataByte inVelocity, + Channel inChannel) { send(NoteOff, inNoteNumber, inVelocity, inChannel); } @@ -226,9 +228,9 @@ void MidiInterface::sendNoteOff(DataByte inNoteNumber, \param inProgramNumber The Program to select (0 to 127). \param inChannel The channel on which the message will be sent (1 to 16). */ -template -void MidiInterface::sendProgramChange(DataByte inProgramNumber, - Channel inChannel) +template +void MidiInterface::sendProgramChange(DataByte inProgramNumber, + Channel inChannel) { send(ProgramChange, inProgramNumber, 0, inChannel); } @@ -239,10 +241,10 @@ void MidiInterface::sendProgramChange(DataByte inProgramNumber, \param inChannel The channel on which the message will be sent (1 to 16). @see MidiControlChangeNumber */ -template -void MidiInterface::sendControlChange(DataByte inControlNumber, - DataByte inControlValue, - Channel inChannel) +template +void MidiInterface::sendControlChange(DataByte inControlNumber, + DataByte inControlValue, + Channel inChannel) { send(ControlChange, inControlNumber, inControlValue, inChannel); } @@ -252,10 +254,10 @@ void MidiInterface::sendControlChange(DataByte inControlNumber, \param inPressure The amount of AfterTouch to apply (0 to 127). \param inChannel The channel on which the message will be sent (1 to 16). */ -template -void MidiInterface::sendPolyPressure(DataByte inNoteNumber, - DataByte inPressure, - Channel inChannel) +template +void MidiInterface::sendPolyPressure(DataByte inNoteNumber, + DataByte inPressure, + Channel inChannel) { send(AfterTouchPoly, inNoteNumber, inPressure, inChannel); } @@ -264,9 +266,9 @@ void MidiInterface::sendPolyPressure(DataByte inNoteNumber, \param inPressure The amount of AfterTouch to apply to all notes. \param inChannel The channel on which the message will be sent (1 to 16). */ -template -void MidiInterface::sendAfterTouch(DataByte inPressure, - Channel inChannel) +template +void MidiInterface::sendAfterTouch(DataByte inPressure, + Channel inChannel) { send(AfterTouchChannel, inPressure, 0, inChannel); } @@ -277,9 +279,9 @@ void MidiInterface::sendAfterTouch(DataByte inPressure, center value is 0. \param inChannel The channel on which the message will be sent (1 to 16). */ -template -void MidiInterface::sendPitchBend(int inPitchValue, - Channel inChannel) +template +void MidiInterface::sendPitchBend(int inPitchValue, + Channel inChannel) { const unsigned bend = inPitchValue - MIDI_PITCHBEND_MIN; send(PitchBend, (bend & 0x7f), (bend >> 7) & 0x7f, inChannel); @@ -292,11 +294,11 @@ void MidiInterface::sendPitchBend(int inPitchValue, and +1.0f (max upwards bend), center value is 0.0f. \param inChannel The channel on which the message will be sent (1 to 16). */ -template -void MidiInterface::sendPitchBend(double inPitchValue, - Channel inChannel) +template +void MidiInterface::sendPitchBend(double inPitchValue, + Channel inChannel) { - const int value = inPitchValue * MIDI_PITCHBEND_MAX; + const int value = inPitchValue * MIDI_PITCHBEND_MAX * Settings::Toto; sendPitchBend(value, inChannel); } @@ -309,29 +311,32 @@ void MidiInterface::sendPitchBend(double inPitchValue, default value for ArrayContainsBoundaries is set to 'false' for compatibility with previous versions of the library. */ -template -void MidiInterface::sendSysEx(unsigned inLength, - const byte* inArray, - bool inArrayContainsBoundaries) +template +void MidiInterface::sendSysEx(unsigned inLength, + const byte* inArray, + bool inArrayContainsBoundaries) { - if (inArrayContainsBoundaries == false) + const bool writeBeginEndBytes = !inArrayContainsBoundaries; + + if (writeBeginEndBytes) { mSerial.write(0xf0); + } - for (unsigned i = 0; i < inLength; ++i) - mSerial.write(inArray[i]); + for (unsigned i = 0; i < inLength; ++i) + { + mSerial.write(inArray[i]); + } + if (writeBeginEndBytes) + { mSerial.write(0xf7); } - else - { - for (unsigned i = 0; i < inLength; ++i) - mSerial.write(inArray[i]); - } -#if MIDI_USE_RUNNING_STATUS - mRunningStatus_TX = InvalidType; -#endif + if (Settings::UseRunningStatus) + { + mRunningStatus_TX = InvalidType; + } } /*! \brief Send a Tune Request message. @@ -339,8 +344,8 @@ void MidiInterface::sendSysEx(unsigned inLength, When a MIDI unit receives this message, it should tune its oscillators (if equipped with any). */ -template -void MidiInterface::sendTuneRequest() +template +void MidiInterface::sendTuneRequest() { sendRealTime(TuneRequest); } @@ -351,9 +356,9 @@ void MidiInterface::sendTuneRequest() \param inValuesNibble MTC data See MIDI Specification for more information. */ -template -void MidiInterface::sendTimeCodeQuarterFrame(DataByte inTypeNibble, - DataByte inValuesNibble) +template +void MidiInterface::sendTimeCodeQuarterFrame(DataByte inTypeNibble, + DataByte inValuesNibble) { const byte data = (((inTypeNibble & 0x07) << 4) | (inValuesNibble & 0x0f)); sendTimeCodeQuarterFrame(data); @@ -365,42 +370,45 @@ void MidiInterface::sendTimeCodeQuarterFrame(DataByte inTypeNibble, \param inData if you want to encode directly the nibbles in your program, you can send the byte here. */ -template -void MidiInterface::sendTimeCodeQuarterFrame(DataByte inData) +template +void MidiInterface::sendTimeCodeQuarterFrame(DataByte inData) { mSerial.write((byte)TimeCodeQuarterFrame); mSerial.write(inData); -#if MIDI_USE_RUNNING_STATUS - mRunningStatus_TX = InvalidType; -#endif + if (Settings::UseRunningStatus) + { + mRunningStatus_TX = InvalidType; + } } /*! \brief Send a Song Position Pointer message. \param inBeats The number of beats since the start of the song. */ -template -void MidiInterface::sendSongPosition(unsigned inBeats) +template +void MidiInterface::sendSongPosition(unsigned inBeats) { mSerial.write((byte)SongPosition); mSerial.write(inBeats & 0x7f); mSerial.write((inBeats >> 7) & 0x7f); -#if MIDI_USE_RUNNING_STATUS - mRunningStatus_TX = InvalidType; -#endif + if (Settings::UseRunningStatus) + { + mRunningStatus_TX = InvalidType; + } } /*! \brief Send a Song Select message */ -template -void MidiInterface::sendSongSelect(DataByte inSongNumber) +template +void MidiInterface::sendSongSelect(DataByte inSongNumber) { mSerial.write((byte)SongSelect); mSerial.write(inSongNumber & 0x7f); -#if MIDI_USE_RUNNING_STATUS - mRunningStatus_TX = InvalidType; -#endif + if (Settings::UseRunningStatus) + { + mRunningStatus_TX = InvalidType; + } } /*! \brief Send a Real Time (one byte) message. @@ -410,8 +418,8 @@ void MidiInterface::sendSongSelect(DataByte inSongNumber) You can also send a Tune Request with this method. @see MidiType */ -template -void MidiInterface::sendRealTime(MidiType inType) +template +void MidiInterface::sendRealTime(MidiType inType) { switch (inType) { @@ -432,18 +440,19 @@ void MidiInterface::sendRealTime(MidiType inType) // Do not cancel Running Status for real-time messages as they can be // interleaved within any message. Though, TuneRequest can be sent here, // and as it is a System Common message, it must reset Running Status. -#if MIDI_USE_RUNNING_STATUS - if (inType == TuneRequest) mRunningStatus_TX = InvalidType; -#endif + if (Settings::UseRunningStatus && inType == TuneRequest) + { + mRunningStatus_TX = InvalidType; + } } /*! @} */ // End of doc group MIDI Output // ----------------------------------------------------------------------------- -template -StatusByte MidiInterface::getStatus(MidiType inType, - Channel inChannel) const +template +StatusByte MidiInterface::getStatus(MidiType inType, + Channel inChannel) const { return ((byte)inType | ((inChannel - 1) & 0x0f)); } @@ -469,16 +478,16 @@ StatusByte MidiInterface::getStatus(MidiType inType, it is sent back on the MIDI output. @see see setInputChannel() */ -template -inline bool MidiInterface::read() +template +inline bool MidiInterface::read() { return read(mInputChannel); } /*! \brief Read messages on a specified channel. */ -template -inline bool MidiInterface::read(Channel inChannel) +template +inline bool MidiInterface::read(Channel inChannel) { if (inChannel >= MIDI_CHANNEL_OFF) return false; // MIDI Input disabled. @@ -506,8 +515,8 @@ inline bool MidiInterface::read(Channel inChannel) // ----------------------------------------------------------------------------- // Private method: MIDI parser -template -bool MidiInterface::parse() +template +bool MidiInterface::parse() { if (mSerial.available() == 0) // No data available. @@ -770,24 +779,26 @@ bool MidiInterface::parse() // Then update the index of the pending message. mPendingMessageIndex++; -#if USE_1BYTE_PARSING - // Message is not complete. - return false; -#else - // Call the parser recursively - // to parse the rest of the message. - return parse(); -#endif + if (Settings::Use1ByteParsing) + { + // Message is not complete. + return false; + } + else + { + // Call the parser recursively to parse the rest of the message. + return parse(); + } } } } // Private method, see midi_Settings.h for documentation -template -inline void MidiInterface::handleNullVelocityNoteOnAsNoteOff() +template +inline void MidiInterface::handleNullVelocityNoteOnAsNoteOff() { - #if MIDI_HANDLE_NULL_VELOCITY_NOTE_ON_AS_NOTE_OFF - if (getType() == NoteOn && getData2() == 0) + if (Settings::HandleNullVelocityNoteOnAsNoteOff && + getType() == NoteOn && getData2() == 0) { mMessage.type = NoteOff; } @@ -795,8 +806,8 @@ inline void MidiInterface::handleNullVelocityNoteOnAsNoteOff() } // Private method: check if the received message is on the listened channel -template -inline bool MidiInterface::inputFilter(Channel inChannel) +template +inline bool MidiInterface::inputFilter(Channel inChannel) { // This method handles recognition of channel // (to know if the message is destinated to the Arduino) @@ -827,8 +838,8 @@ inline bool MidiInterface::inputFilter(Channel inChannel) } // Private method: reset input attributes -template -inline void MidiInterface::resetInput() +template +inline void MidiInterface::resetInput() { mPendingMessageIndex = 0; mPendingMessageExpectedLenght = 0; @@ -841,8 +852,8 @@ inline void MidiInterface::resetInput() Returns an enumerated type. @see MidiType */ -template -MidiType MidiInterface::getType() const +template +MidiType MidiInterface::getType() const { return mMessage.type; } @@ -852,22 +863,22 @@ MidiType MidiInterface::getType() const \return Channel range is 1 to 16. For non-channel messages, this will return 0. */ -template -Channel MidiInterface::getChannel() const +template +Channel MidiInterface::getChannel() const { return mMessage.channel; } /*! \brief Get the first data byte of the last received message. */ -template -DataByte MidiInterface::getData1() const +template +DataByte MidiInterface::getData1() const { return mMessage.data1; } /*! \brief Get the second data byte of the last received message. */ -template -DataByte MidiInterface::getData2() const +template +DataByte MidiInterface::getData2() const { return mMessage.data2; } @@ -876,8 +887,8 @@ DataByte MidiInterface::getData2() const @see getSysExArrayLength to get the array's length in bytes. */ -template -const byte* MidiInterface::getSysExArray() const +template +const byte* MidiInterface::getSysExArray() const { return mMessage.sysexArray; } @@ -887,24 +898,25 @@ const byte* MidiInterface::getSysExArray() const It is coded using data1 as LSB and data2 as MSB. \return The array's length, in bytes. */ -template -unsigned MidiInterface::getSysExArrayLength() const +template +unsigned MidiInterface::getSysExArrayLength() const { - const unsigned size = ((unsigned)(mMessage.data2) << 8) | mMessage.data1; - return (size > MIDI_SYSEX_ARRAY_SIZE) ? MIDI_SYSEX_ARRAY_SIZE : size; + static const unsigned maxSize = Settings::SysExArraySize; + const unsigned size = (unsigned(mMessage.data2) << 8) | mMessage.data1; + return (size > maxSize) ? maxSize : size; } /*! \brief Check if a valid message is stored in the structure. */ -template -bool MidiInterface::check() const +template +bool MidiInterface::check() const { return mMessage.valid; } // ----------------------------------------------------------------------------- -template -Channel MidiInterface::getInputChannel() const +template +Channel MidiInterface::getInputChannel() const { return mInputChannel; } @@ -913,8 +925,8 @@ Channel MidiInterface::getInputChannel() const \param inChannel the channel value. Valid values are 1 to 16, MIDI_CHANNEL_OMNI if you want to listen to all channels, and MIDI_CHANNEL_OFF to disable input. */ -template -void MidiInterface::setInputChannel(Channel inChannel) +template +void MidiInterface::setInputChannel(Channel inChannel) { mInputChannel = inChannel; } @@ -926,8 +938,8 @@ void MidiInterface::setInputChannel(Channel inChannel) This is a utility static method, used internally, made public so you can handle MidiTypes more easily. */ -template -MidiType MidiInterface::getTypeFromStatusByte(byte inStatus) +template +MidiType MidiInterface::getTypeFromStatusByte(byte inStatus) { if ((inStatus < 0x80) || (inStatus == 0xf4) || @@ -949,14 +961,14 @@ MidiType MidiInterface::getTypeFromStatusByte(byte inStatus) /*! \brief Returns channel in the range 1-16 */ -template -inline Channel MidiInterface::getChannelFromStatusByte(byte inStatus) +template +inline Channel MidiInterface::getChannelFromStatusByte(byte inStatus) { return (inStatus & 0x0f) + 1; } -template -bool MidiInterface::isChannelMessage(MidiType inType) +template +bool MidiInterface::isChannelMessage(MidiType inType) { return (inType == NoteOff || inType == NoteOn || @@ -975,24 +987,24 @@ bool MidiInterface::isChannelMessage(MidiType inType) @{ */ -template void MidiInterface::setHandleNoteOff(void (*fptr)(byte channel, byte note, byte velocity)) { mNoteOffCallback = fptr; } -template void MidiInterface::setHandleNoteOn(void (*fptr)(byte channel, byte note, byte velocity)) { mNoteOnCallback = fptr; } -template void MidiInterface::setHandleAfterTouchPoly(void (*fptr)(byte channel, byte note, byte pressure)) { mAfterTouchPolyCallback = fptr; } -template void MidiInterface::setHandleControlChange(void (*fptr)(byte channel, byte number, byte value)) { mControlChangeCallback = fptr; } -template void MidiInterface::setHandleProgramChange(void (*fptr)(byte channel, byte number)) { mProgramChangeCallback = fptr; } -template void MidiInterface::setHandleAfterTouchChannel(void (*fptr)(byte channel, byte pressure)) { mAfterTouchChannelCallback = fptr; } -template void MidiInterface::setHandlePitchBend(void (*fptr)(byte channel, int bend)) { mPitchBendCallback = fptr; } -template void MidiInterface::setHandleSystemExclusive(void (*fptr)(byte* array, byte size)) { mSystemExclusiveCallback = fptr; } -template void MidiInterface::setHandleTimeCodeQuarterFrame(void (*fptr)(byte data)) { mTimeCodeQuarterFrameCallback = fptr; } -template void MidiInterface::setHandleSongPosition(void (*fptr)(unsigned beats)) { mSongPositionCallback = fptr; } -template void MidiInterface::setHandleSongSelect(void (*fptr)(byte songnumber)) { mSongSelectCallback = fptr; } -template void MidiInterface::setHandleTuneRequest(void (*fptr)(void)) { mTuneRequestCallback = fptr; } -template void MidiInterface::setHandleClock(void (*fptr)(void)) { mClockCallback = fptr; } -template void MidiInterface::setHandleStart(void (*fptr)(void)) { mStartCallback = fptr; } -template void MidiInterface::setHandleContinue(void (*fptr)(void)) { mContinueCallback = fptr; } -template void MidiInterface::setHandleStop(void (*fptr)(void)) { mStopCallback = fptr; } -template void MidiInterface::setHandleActiveSensing(void (*fptr)(void)) { mActiveSensingCallback = fptr; } -template void MidiInterface::setHandleSystemReset(void (*fptr)(void)) { mSystemResetCallback = fptr; } +template void MidiInterface::setHandleNoteOff(void (*fptr)(byte channel, byte note, byte velocity)) { mNoteOffCallback = fptr; } +template void MidiInterface::setHandleNoteOn(void (*fptr)(byte channel, byte note, byte velocity)) { mNoteOnCallback = fptr; } +template void MidiInterface::setHandleAfterTouchPoly(void (*fptr)(byte channel, byte note, byte pressure)) { mAfterTouchPolyCallback = fptr; } +template void MidiInterface::setHandleControlChange(void (*fptr)(byte channel, byte number, byte value)) { mControlChangeCallback = fptr; } +template void MidiInterface::setHandleProgramChange(void (*fptr)(byte channel, byte number)) { mProgramChangeCallback = fptr; } +template void MidiInterface::setHandleAfterTouchChannel(void (*fptr)(byte channel, byte pressure)) { mAfterTouchChannelCallback = fptr; } +template void MidiInterface::setHandlePitchBend(void (*fptr)(byte channel, int bend)) { mPitchBendCallback = fptr; } +template void MidiInterface::setHandleSystemExclusive(void (*fptr)(byte* array, byte size)) { mSystemExclusiveCallback = fptr; } +template void MidiInterface::setHandleTimeCodeQuarterFrame(void (*fptr)(byte data)) { mTimeCodeQuarterFrameCallback = fptr; } +template void MidiInterface::setHandleSongPosition(void (*fptr)(unsigned beats)) { mSongPositionCallback = fptr; } +template void MidiInterface::setHandleSongSelect(void (*fptr)(byte songnumber)) { mSongSelectCallback = fptr; } +template void MidiInterface::setHandleTuneRequest(void (*fptr)(void)) { mTuneRequestCallback = fptr; } +template void MidiInterface::setHandleClock(void (*fptr)(void)) { mClockCallback = fptr; } +template void MidiInterface::setHandleStart(void (*fptr)(void)) { mStartCallback = fptr; } +template void MidiInterface::setHandleContinue(void (*fptr)(void)) { mContinueCallback = fptr; } +template void MidiInterface::setHandleStop(void (*fptr)(void)) { mStopCallback = fptr; } +template void MidiInterface::setHandleActiveSensing(void (*fptr)(void)) { mActiveSensingCallback = fptr; } +template void MidiInterface::setHandleSystemReset(void (*fptr)(void)) { mSystemResetCallback = fptr; } /*! \brief Detach an external function from the given type. @@ -1000,8 +1012,8 @@ template void MidiInterface::setHandleSystemReset( \param inType The type of message to unbind. When a message of this type is received, no function will be called. */ -template -void MidiInterface::disconnectCallbackFromType(MidiType inType) +template +void MidiInterface::disconnectCallbackFromType(MidiType inType) { switch (inType) { @@ -1031,8 +1043,8 @@ void MidiInterface::disconnectCallbackFromType(MidiType inType) /*! @} */ // End of doc group MIDI Callbacks // Private - launch callback function based on received type. -template -void MidiInterface::launchCallback() +template +void MidiInterface::launchCallback() { // The order is mixed to allow frequent messages to trigger their callback faster. switch (mMessage.type) @@ -1092,8 +1104,8 @@ void MidiInterface::launchCallback() @see MidiFilterMode */ -template -void MidiInterface::setThruFilterMode(MidiFilterMode inThruFilterMode) +template +void MidiInterface::setThruFilterMode(MidiFilterMode inThruFilterMode) { mThruFilterMode = inThruFilterMode; if (mThruFilterMode != Off) @@ -1102,27 +1114,27 @@ void MidiInterface::setThruFilterMode(MidiFilterMode inThruFilterMod mThruActivated = false; } -template -MidiFilterMode MidiInterface::getFilterMode() const +template +MidiFilterMode MidiInterface::getFilterMode() const { return mThruFilterMode; } -template -bool MidiInterface::getThruState() const +template +bool MidiInterface::getThruState() const { return mThruActivated; } -template -void MidiInterface::turnThruOn(MidiFilterMode inThruFilterMode) +template +void MidiInterface::turnThruOn(MidiFilterMode inThruFilterMode) { mThruActivated = true; mThruFilterMode = inThruFilterMode; } -template -void MidiInterface::turnThruOff() +template +void MidiInterface::turnThruOff() { mThruActivated = false; mThruFilterMode = Off; @@ -1136,8 +1148,8 @@ void MidiInterface::turnThruOff() // to output unless filter is set to Off. // - Channel messages are passed to the output whether their channel // is matching the input channel and the filter setting -template -void MidiInterface::thruFilter(Channel inChannel) +template +void MidiInterface::thruFilter(Channel inChannel) { // If the feature is disabled, don't do anything. if (!mThruActivated || (mThruFilterMode == Off)) diff --git a/src/midi_Defs.h b/src/midi_Defs.h index 324f361..dc2b29a 100644 --- a/src/midi_Defs.h +++ b/src/midi_Defs.h @@ -207,11 +207,12 @@ struct Message #define MIDI_CREATE_INSTANCE(Type, SerialPort, Name) \ midi::MidiInterface Name((Type&)SerialPort); -/*! \brief Shortcut for MIDI Interface class with template argument. - The class name for a MIDI object using the hardware UART would be - midi::MidiInterface, when the macro is MIDI_CLASS(HardwareSerial). +/*! \brief Create an instance of the library attached to a serial port with + custom settings. + @see DefaultSettings + @see MIDI_CREATE_INSTANCE */ -#define MIDI_CLASS(Type) \ - midi::MidiInterface +#define MIDI_CREATE_CUSTOM_INSTANCE(Type, SerialPort, Name, Settings) \ + midi::MidiInterface Name((Type&)SerialPort); END_MIDI_NAMESPACE diff --git a/src/midi_Settings.h b/src/midi_Settings.h index cd2d021..f2ea338 100644 --- a/src/midi_Settings.h +++ b/src/midi_Settings.h @@ -99,4 +99,24 @@ BEGIN_MIDI_NAMESPACE +/*! \brief Default Settings Traits struct + 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: + struct MySettings : public midi::DefaultSettings + { + static const bool UseRunningStatus = false; // Messes with my old equipment! + }; + MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial2, midi, MySettings); + */ +struct DefaultSettings +{ + static const bool UseRunningStatus = true; + static const bool HandleNullVelocityNoteOnAsNoteOff = true; + static const bool Use1ByteParsing = true; + static const unsigned BaudRate = 31250; + static const unsigned SysExArraySize = 128; +}; + END_MIDI_NAMESPACE