The ALSA MIDI Filter (AMF) runs as an ALSA MIDI client, connects to a configurable set of MIDI clients for input, processes its input (MIDI event data) based on its configuration and the type and content of the MIDI input, and sends the result to one or more connected MIDI output clients.

https://github.com/jjttcc/midifilter
https://sourceforge.net/projects/midifilter/
  
I developed this application after looking into current MIDI filtering packages for Linux (such as mididings and midish) and not being satisfied with what I can do with them.  AMF is implemented in perl, using the MIDI::ALSA module, and is intended to be an open-ended project that will grow and evolve as needed.  Anyone interested is welcome to add their own features and modifications - submit patches for consideration, fork it, or etc.  The license is GPL v2.  If you're not a developer/hacker, you're welcome to submit suggestions for additional functionality and improvements.  And, of course, bug reports are welcome.

Current MIDI-event filtering features:

  - program-change - From note event where patch number is determined by the pitch value.
  - bank-select - switch to the next/previous bank.
  - transpositions - Transpose pitches within a certain configured range up
    or down by a specified number of half steps.
  - Run external commands.
  - Real-time START, STOP, and CONTINUE messages.
  - MIDI machine control messages.
  - Trigger a mode (which I call "program-change sample mode") that cycles through the entire range of patches, with a pause in between each patch change.  In other words, it sends patch 0, pauses for a configured number of seconds, sends patch 1, etc., until it has reached patch 127. This allows the user to try out - "sample" - each patch of the current bank
without having to explicitly invoke a program change.