ALSA Sequencer to plain text and back
  • C 79.8%
  • Makefile 16.2%
  • Shell 4%
Find a file
2026-02-22 10:44:08 +01:00
.gitignore Add cross compilation 2026-02-20 07:53:48 +01:00
CHANGELOG.md Exit when stdin closes 2026-02-22 10:44:08 +01:00
crosscompile.container Add cross compilation 2026-02-20 07:53:48 +01:00
LICENSE Cleanup, handle more midi messages, add LICENSE and README 2026-02-19 08:46:18 +01:00
Makefile More standard makefile, install man page, allow injecting CFLAGS/LDFLAGS/PREFIX/DESTDIR 2026-02-20 08:16:23 +01:00
midipipe.1.md Add version flag 2026-02-20 07:54:58 +01:00
midipipe.c Exit when stdin closes 2026-02-22 10:44:08 +01:00
README.md Exit when stdin closes 2026-02-22 10:44:08 +01:00
twistertop.sh Cleanup, handle more midi messages, add LICENSE and README 2026-02-19 08:46:18 +01:00

midipipe - MIDI from stdin and to stdout

midipipe(1) is a Linux program that accepts MIDI events in a plain text format on stdin, and sends them to a MIDI device or client using the ALSA sequencer API, and vice versa.

echo 'ch 1 note_on 60 127' | midipipe | grep 'ch 2 cc'

It keeps a persistent client, so while you can send a single message like in this example, you can also continuously stream messages in or out, which is where midipipe shines.

Use it in your shell scripts, or really anywhere where you don't have a proper MIDI API available, but you are able to shell out and write to/from a sub-process. It also makes a great "MIDI monitor", to see exactly the messages a device or program is emitting.

Events are always sent in (or near) real time, midipipe does not handle timestamps.

Installation

There are per-built binaries available on the releases page, or build it from source (see below).

Design and Usage

midipipe - MIDI message to and from plain text pipe

OPTIONS:
  -i, --input <dev>     Connect device for input
  -o, --output <dev>    Connect device for output
  -d, --device <dev>    Connect device for input and output
  -c, --client <name>   Name of the ALSA client, default 'midipipe'
  -v, --version         Print version information and exit
  -l, --list            List devices
  -h, --help            Show this output

midipipe uses the ALSA Sequencer API, not the more low-level ALSA Rawmidi API. With Rawmidi, only one process can access a device at the same time. With Sequencer, you get a "client" with an input and output port, which can be connected to multiple devices, or routed to other clients. Sequencer also plays nicely with modern Pipewire setups, allowing you to freely interconnect ALSA/Jack/Pulseaudio/Pipewire applications.

midipipe can setup connections for you when it starts (see --input/--output/--device), or you can set them up yourself through aconnect, once or the patch bay application of your choice.

  • --list, -l — List devices
  • --input, -i — Specify an input device (a device midipipe will read from)
  • --output, -o — Specify an output device (a device midipipe will write to)
  • --device, -d — Combination of -i and -o, connect to the same device for input and output

Devices can be specified with ALSA address numbers, e.g. midipipe -d 28:0, or by name. A partial prefix of the name is enough. So to connect to 28:0 - Midi Fighter Twister MIDI 1, any of the following work:

midipipe -d 28:0
midipipe -d 'Midi Fighter Twister MIDI 1'
midipipe -d 'Midi Fighter'
midipipe -d 'Midi F'

MIDI Message Format

MIDI messages are represented as line-based text, each line representing a single MIDI message of a given type on a given channel. Channel numbers are 1-indexed (1-16).

Message Type Text Format Notes
Note On ch <1-16> note_on <note> Velocity = 127
Note On ch <1-16> note_on <note> <velocity>
Note Off ch <1-16> note_off <note>
Controller ch <1-16> cc <param> <value>
Program Change ch <1-16> pgm <value>
Channel Pressure ch <1-16> pressure <value>
Key Pressure ch <1-16> keypress <note> <value>
Pitch Bend ch <1-16> bend <0-16383>

Values for <note>, <value>, <velocity>, <param> are in the 0-127 range.

Building

To build the midipipe binary

make

To cross-compile multiple architectures (requires podman):

make cross-build

To build the man page (requires pandoc)

make man

Installation

sudo make install

To uninstall

sudo make uninstall

These will honor $PREFIX and/or $DESTDIR.

Examples

The included twistertop.sh is a shell script that you can pipe into midipipe: ./twistertop.sh | midipipe -d '...', and which will use the LEDs on a MIDI Fighter Twister controller to show current CPU load.

Shell tips

In bash you can use coproc to get a subprocess with file descriptors you can read from or write to:

#!/bin/bash

coproc MIDI { ./midipipe "$@"; }

# Write to midipipe
echo "ch 1 note_on 60" >&"${MIDI[1]}"
sleep 0.5
echo "ch 1 note_on 62" >&"${MIDI[1]}"
sleep 0.5
echo "ch 1 note_on 64" >&"${MIDI[1]}"

# Read from midipipe
while true; do
    read -u "${MIDI[0]}" _ chan type p1 p2
    echo "Midi says: channel $chan, message $type, $p1, $p2"
done

Dependencies

  • ALSA development libraries (libasound2-dev on Ubuntu/Debian)
  • Standard C library development tools
  • pandoc for the man page
  • podman for cross compilation

License

© Copyright Arne Brasseur 2026. Licensed under the EUPL, see LICENSE.