adds new thru mode: "UnmutedChannels"

This commit is contained in:
Eric Sherman 2021-07-31 20:34:09 -04:00
parent d501f4bb3d
commit 8b8d93e937
No known key found for this signature in database
GPG Key ID: 5FF6E54D61748174
4 changed files with 139 additions and 0 deletions

View File

@ -242,6 +242,7 @@ public:
inline void turnThruOn(Thru::Mode inThruFilterMode = Thru::Full); inline void turnThruOn(Thru::Mode inThruFilterMode = Thru::Full);
inline void turnThruOff(); inline void turnThruOff();
inline void setThruFilterMode(Thru::Mode inThruFilterMode); inline void setThruFilterMode(Thru::Mode inThruFilterMode);
inline void setThruMutedChannels(bool (&inThruMutedChannels)[17]);
private: private:
void thruFilter(byte inChannel); void thruFilter(byte inChannel);
@ -279,6 +280,7 @@ private:
unsigned mCurrentNrpnNumber; unsigned mCurrentNrpnNumber;
bool mThruActivated : 1; bool mThruActivated : 1;
Thru::Mode mThruFilterMode : 7; Thru::Mode mThruFilterMode : 7;
bool mThruMutedChannels[17];
MidiMessage mMessage; MidiMessage mMessage;
unsigned long mLastMessageSentTime; unsigned long mLastMessageSentTime;
unsigned long mLastMessageReceivedTime; unsigned long mLastMessageReceivedTime;

View File

@ -1355,6 +1355,12 @@ inline void MidiInterface<Transport, Settings, Platform>::setThruFilterMode(Thru
mThruActivated = mThruFilterMode != Thru::Off; mThruActivated = mThruFilterMode != Thru::Off;
} }
template<class Transport, class Settings, class Platform>
inline void MidiInterface<Transport, Settings, Platform>::setThruMutedChannels(bool (&inThruMutedChannels)[17])
{
memcpy(mThruMutedChannels, inThruMutedChannels, sizeof(inThruMutedChannels));
}
template<class Transport, class Settings, class Platform> template<class Transport, class Settings, class Platform>
inline Thru::Mode MidiInterface<Transport, Settings, Platform>::getFilterMode() const inline Thru::Mode MidiInterface<Transport, Settings, Platform>::getFilterMode() const
{ {
@ -1439,6 +1445,17 @@ void MidiInterface<Transport, Settings, Platform>::thruFilter(Channel inChannel)
} }
break; break;
case Thru::UnmutedChannels:
if ((mMessage.type == NoteOff) ||
(!mThruMutedChannels[0] && !mThruMutedChannels[mMessage.channel]))
{
send(mMessage.type,
mMessage.data1,
mMessage.data2,
mMessage.channel);
}
break;
default: default:
break; break;
} }

View File

@ -132,6 +132,7 @@ struct Thru
Full = 1, ///< Fully enabled Thru (every incoming message is sent back). Full = 1, ///< Fully enabled Thru (every incoming message is sent back).
SameChannel = 2, ///< Only the messages on the Input Channel will be 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. DifferentChannel = 3, ///< All the messages but the ones on the Input Channel will be sent back.
UnmutedChannels = 4, ///< Only the messages on channels that are not muted will be sent back.
}; };
}; };

View File

@ -386,4 +386,123 @@ TEST(MidiThru, invalidMode)
EXPECT_EQ(serial.mTxBuffer.getLength(), 0); EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
} }
TEST(MidiThru, unmutedChannelsNoneMuted) // acts like full
{
SerialMock serial;
Transport transport(serial);
MidiInterface midi((Transport&)transport);
Buffer buffer;
midi.begin(MIDI_CHANNEL_OMNI);
midi.setThruFilterMode(midi::Thru::UnmutedChannels);
static const unsigned rxSize = 6;
static const byte rxData[rxSize] = { 0x9b, 12, 34, 0x9c, 56, 78 };
serial.mRxBuffer.write(rxData, rxSize);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
EXPECT_EQ(midi.read(), true);
buffer.clear();
buffer.resize(3);
EXPECT_EQ(serial.mTxBuffer.getLength(), 3);
serial.mTxBuffer.read(&buffer[0], 3);
EXPECT_THAT(buffer, ElementsAreArray({
0x9b, 12, 34
}));
buffer.clear();
buffer.resize(3);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
EXPECT_EQ(midi.read(), true);
EXPECT_EQ(serial.mTxBuffer.getLength(), 3); // Not using TX running status
serial.mTxBuffer.read(&buffer[0], 3);
EXPECT_THAT(buffer, ElementsAreArray({
0x9c, 56, 78
}));
}
TEST(MidiThru, unmutedChannelsWithMutedChannelTwelve)
{
SerialMock serial;
Transport transport(serial);
MidiInterface midi((Transport&)transport);
Buffer buffer;
midi.begin(MIDI_CHANNEL_OMNI);
midi.setThruFilterMode(midi::Thru::UnmutedChannels);
bool thruMutedChannels[17] = {
false,
false, false, false, false, false, false, false, false,
false, false, false, true, false, false, false, false
};
midi.setThruMutedChannels(thruMutedChannels);
static const unsigned rxSize = 6;
static const byte rxData[rxSize] = { 0x9b, 12, 34, 0x9c, 56, 78 };
serial.mRxBuffer.write(rxData, rxSize);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(midi.read(), true);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(midi.read(), true);
buffer.clear();
buffer.resize(3);
EXPECT_EQ(serial.mTxBuffer.getLength(), 3);
serial.mTxBuffer.read(&buffer[0], 3);
EXPECT_THAT(buffer, ElementsAreArray({
0x9c, 56, 78
}));
}
TEST(MidiThru, unmutedChannelsWithChannelZeroMuted) // acts like off
{
SerialMock serial;
Transport transport(serial);
MidiInterface midi((Transport&)transport);
Buffer buffer;
midi.begin(MIDI_CHANNEL_OMNI);
midi.setThruFilterMode(midi::Thru::UnmutedChannels);
bool thruMutedChannels[17] = {
true,
false, false, false, false, false, false, false, false,
false, false, false, true, false, false, false, false
};
midi.setThruMutedChannels(thruMutedChannels);
static const unsigned rxSize = 6;
static const byte rxData[rxSize] = { 0x9b, 12, 34, 0x9c, 56, 78 };
serial.mRxBuffer.write(rxData, rxSize);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
EXPECT_EQ(midi.read(), true);
EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
EXPECT_EQ(midi.read(), false);
EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
EXPECT_EQ(midi.read(), true);
EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
}
END_UNNAMED_NAMESPACE END_UNNAMED_NAMESPACE