Git Product home page Git Product logo

receivemidi's Introduction

ReceiveMIDI

ReceiveMIDI is a multi-platform command-line tool makes it very easy to quickly receive and monitor MIDI messages from MIDI devices on your computer.

All the heavy lifting is done by the wonderful JUCE library.

The project website is https://github.com/gbevin/ReceiveMIDI

Community

Join the Forums: https://forum.uwyn.com

Chat on Discord: https://discord.gg/sKM6pE575y

Purpose

This tool is mainly intended for quickly monitoring the messages that are sent to your computer from a particular MIDI device. By providing filter commands, it's possible to only focus on particular MIDI messages.

Here's a tutorial video about both SendMIDI and ReceiveMIDI, including some tips and tricks of how to use the command-line on macOS:

Tutorial Video

ShowMIDI

If you're looking for a beautiful GUI to effortlessly visualize MIDI activity without having to wade through log files, please take a look at my other tool ShowMIDI: https://github.com/gbevin/ShowMIDI

Download

You can download pre-built ReceiveMIDI binaries from the release section: https://github.com/gbevin/ReceiveMIDI/releases

Since ReceiveMIDI is free and open-source, you can also easily build it yourself. Just take a look into the Builds directory when you download the sources.

If you're using the macOS Homebrew package manager, you can install ReceiveMIDI with:

brew install gbevin/tools/receivemidi

Usage

To use it, simply type "receivemidi" or "receivemidi.exe" on the command line and follow it with a series of commands that you want to execute. These commands have purposefully been chosen to be concise and easy to remember, so that it's extremely fast and intuitive to quickly receive or monitor MIDI messages.

These are all the supported commands:

  dev   name       Set the name of the MIDI input port
  virt  (name)     Use virtual MIDI port with optional name (Linux/macOS)
  pass  name       Set name of MIDI output port for MIDI pass-through
  list             Lists the MIDI input ports
  file  path       Loads commands from the specified program file
  dec              Interpret the next numbers as decimals by default
  hex              Interpret the next numbers as hexadecimals by default
  ch    number     Set MIDI channel for the commands (0-16), defaults to 0
  ts               Output a timestamp for each received MIDI message
  nn               Output notes as numbers instead of names
  omc   number     Set octave for middle C, defaults to 3
  voice            Show all Channel Voice messages
  note             Show all Note messages
  on    (note)     Show Note On, optionally for note (0-127)
  off   (note)     Show Note Off, optionally for note (0-127)
  pp    (note)     Show Poly Pressure, optionally for note (0-127)
  cc    (number)   Show Control Change, optionally for controller (0-127)
  cc14  (number)   Show 14-bit CC, optionally for controller (0-63)
  nrpn  (number)   Show NRPN, optionally for parameter (0-16383)
  nrpnf (number)   Show full NRPN (MSB+LSB), optionally for parameter (0-16383)
  rpn   (number)   Show RPN, optionally for parameter (0-16383)
  rpnf  (number)   Show full RPN (MSB+LSB), optionally for parameter (0-16383)
  pc    (number)   Show Program Change, optionally for program (0-127)
  cp               Show Channel Pressure
  pb               Show Pitch Bend
  sr               Show all System Real-Time messages
  clock            Show Timing Clock
  start            Show Start
  stop             Show Stop
  cont             Show Continue
  as               Show Active Sensing
  rst              Show Reset
  sc               Show all System Common messages
  syx              Show System Exclusive
  syf   path       Store SysEx into a .syx file
  tc               Show MIDI Time Code Quarter Frame
  spp              Show Song Position Pointer
  ss               Show Song Select
  tun              Show Tune Request
  q                Don't show the received messages on standard output
  dump             Dump the received messages 1:1 on standard output
  js    code       Execute this script for each received MIDI message
  jsf   path       Execute the script in this file for each message
  mpp   name       Configure responder MPE Profile creating virtual MIDI input
        manager    and output ports with the provided name, available manager
        members    channel (1-15 or 0 for any) and desired member channel
                   count (1-15, or 0 for any) (Linux/macOS)
  mcr   flag       Sets MPE Profile channel response feature (0-1)
  mpb   flag       Sets MPE Profile pitch bend feature (0-1)
  mcp   flag       Sets MPE Profile channel pressure feature (0-2)
  m3d   flag       Sets MPE Profile 3rd dimension feature (0-2)
  -h  or  --help   Print Help (this message) and exit
  --version        Print version information and exit
  --               Read commands from standard input until it's closed

Alternatively, you can use the following long versions of the commands:

  device virtual pass-through decimal hexadecimal channel timestamp
  note-numbers octave-middle-c note-on note-off poly-pressure control-change
  control-change-14 nrpn-full rpn-full program-change channel-pressure
  pitch-bend system-realtime continue active-sensing reset system-common
  system-exclusive system-exclusive-file time-code song-position song-select
  tune-request quiet javascript javascript-file mpe-profile mpe-channel-reponse
  mpe-pitch-bend mpe-channel-pressure mpe-3rd-dimension

By default, numbers are interpreted in the decimal system, this can be changed to hexadecimal by sending the "hex" command. Additionally, by suffixing a number with "M" or "H", it will be interpreted as a decimal or hexadecimal respectively.

The MIDI device name doesn't have to be an exact match. If ReceiveMIDI can't find the exact name that was specified, it will pick the first MIDI output port that contains the provided text, irrespective of case.

Where notes can be provided as arguments, they can also be written as note names, by default from C-2 to G8 which corresponds to note numbers 0 to 127. By setting the octave for middle C, the note name range can be changed. Sharps can be added by using the "#" symbol after the note letter, and flats by using the letter "b".

For details on how to use the "javascript" and "javascript-file" commands, please refer to the JAVASCRIPT.md documentation file.

Examples

Here are a few examples to get you started:

List all the available MIDI output ports on your system

receivemidi list

Receive all the MIDI messages coming from LinnStrument:

receivemidi dev "LinnStrument MIDI"

Receive only notes coming from LinnStrument:

receivemidi dev "LinnStrument MIDI" note

Receive all voice messages coming from LinnStrument, and also MIDI clock start and stop, all displayed with a timestamp:

receivemidi dev "LinnStrument MIDI" ts voice start stop

Receive all messages from LinnStrument and pipe them to the SendMIDI tool in order to forward them to Bidule:

receivemidi dev linnstrument | sendmidi dev "Bidule  1" --

Receive all messages from LinnStrument. Through the JavaScript feature, each note on will execute the test.sh command with the note number as argument.

receivemidi dev linnstrument
  js "if (MIDI.isNoteOn()) Util.command('/path/to/test.sh ' + MIDI.noteNumber());"

Receive all messages from LinnStrument and don't print them out. Through the JavaScript feature, each note on message will send an OSC message to 127.0.0.1:12800.

receivemidi dev linnstrument quiet
  javascript "if (MIDI.isNoteOn()) OSC.connect('127.0.0.1', 12800).send('/note-on', MIDI.noteNumber());"

Text File Format

The text file that can be read through the "file" command can contain a list of commands and options, just like when you would have written them manually on the console (without the "sendmidi" executable). You can insert new lines instead of spaces and any line that starts with a hash (#) character is a comment.

For instance, this is a text file for one of the examples above:

dev "LinnStrument MIDI"
# timestamp the output
ts
# show all voice messages
voice
# show MIDI clock start and stop
start stop

Building on Linux

To build ReceiveMIDI on Linux you need a minimal set of packages installed beforehand, on Ubuntu this can be done with:

sudo apt install build-essential pkg-config libasound2-dev

After that, go to the LinuxMakeFile directory

cd Builds/LinuxMakeFile

and build the binary by typing make

make

The resulting binary will be in the Build/LinuxMakeFile/build directory and can be moved anywhere appropriate on your system, for instance into /usr/local/bin:

sudo mv build/receivemidi /usr/local/bin

SendMIDI compatibility

The output of the ReceiveMIDI tool is compatible with the SendMIDI tool, allowing you to store MIDI message sequences and play them back later. By using Unix-style pipes on the command-line, it's even possible to chain the receivemidi and sendmidi commands in order to forward MIDI messages.

If you changed the octave for middle C or are outputting hexadecimal numbers instead of the default decimal numbers, make sure that you set up SendMIDI with the same parameters.

SendMIDI can be downloaded from https://github.com/gbevin/SendMIDI

receivemidi's People

Contributors

gbevin avatar plan44 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

receivemidi's Issues

ReceiveOsc, SendOsc

Just thought for a moment how it would be having also ReceiveOsc and SendOsc, then we could create easily cross variants like ReceiveOsc | SendMidi, or ReceiveOsc and triggering some shell script, similarly as possible with ReceiveMidi already. My main use case would be triggering scripts from xbox360 game controller. Scripts which contain SendMidi :-) , converting xbox360 to midi controllers, which can be useful if you want to trigger things independently of active windows, here midi events are very useful, they pass through any window selection or non-selection.

Thanks for sharing your great work.

Juce Timer runs with realtime priority from jackd settings

I've been having trouble with automated scripts running jackd and receivemidi. Sometimes they end up causing RT throttling, which makes the system unresponsive. I checked with "top -H", and receivemidi was running with the -70 realtime priority I assign to jackd in it's command line. I changed the receive midi invocation to use the nice command, and that stopped receivemidi form having -70 priority, but a thread called "Juce Timer" now appears with -70 priority.

Is there a way to get JUCE to stop trying to use my jackd priority settings?

I thought that receivemidi operated only on ALSA ports, so why is it even looking at jackd?

thanks,
-Ted

output / input redirection on windows

Hi. I know these utilities are developed primarily for linux and mac. But i would like to get redirection working on windows command prompt. Perhaps this could be allowed as an 'issue' to help other windows users? Windows command prompt allows you to use a > much like a pipe | on unix. The text output of command 1 is fed into command 2. I would expect receivemidi > sendmidi to work as the default behaviour is to log out the commands in a way that sendmidi understands. I think it is the input ti sendmidi that is not working. receivemidi > log.txt works fine. Does anyone know how to make it work?

Linux missing libraries.

I have the following missing libraries on Ubuntu 20.04.

sendmidi: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.33' not found (required by sendmidi) sendmidi: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.32' not found (required by sendmidi)
sendmidi: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.34' not found (required by sendmidi) sendmidi: /lib/x86_64-linux-gnu/libstdc++.so.6: version GLIBCXX_3.4.29' not found (required by sendmidi)

I compiled it and works fine.

Can't receive MIDI stream in Hex format

Unable to receive MIDI messages in hex format, I've typed the command but I receive all the messages in decimal, I've typed the following command: "receivemidi dev Driver IAC Bus 1 hex" but the data stream is still in decimal numbers.

Triggering a script only when a specified sequence of midi notes are received? How?

Thanks for sendmidi and receivemidi Geert!

I like the script triggering feature of receivemidi a lot.

js    code       Execute this script for each received MIDI message
jsf   path       Execute the script in this file for each message

How could I trigger a script when a sequence of notes is received?

Example: If note pitches 60,61,62 in this order is received (no matter how long or short each note is, only note on sequences could be considered, ignoring note off events). The script should not trigger for 60. Also not for 61. Also not for 62. Also not for 60,61. Also not for 60,62. Also not for 61,62. But the triple combination 60,61,62 it should trigger.

Is there any simple technique available how this could be achieved? Maybe you tried anything similar already? I know this technique from Sequetron by Phil Tipping which is its main feature. Sequetron sequencer can be controlled entirely by commands which trigger on midi note sequences.

This can be useful if the midi space should be used similarly, but this time using receivemidi, opening it for general use cases.

Commands from program file

Hi,

Thanks for this kindly tool! But how to check on different notes and execute a script. This is my command file:

dev microKEY2
on C5 js "if (MIDI.isNoteOn()) Util.command('notepad.exe');"
on B4 js "if (MIDI.isNoteOn()) Util.command('taskkill /f /im notepad.exe');"

But that will not work. How to combine two actions in the command file?

Ability to launch arbitrary command when an event is received?

Hi! First of all, thanks for the wonderful tools. I was wondering if there is a way to have an incoming MIDI event trigger a specific command on the operating system, such as running another executable or shell script. I tried to read through the code, but I don't know C++ well enough to see if this is easy to add, or how to go about it.

I'm happy to try to learn if you could point me to the right spot in the codebase, I can't tell if this would be implemented here or in JUICE lib.

Multiple devices with same name

Hi, I'm looking to "proxy" traffic from one computer, to a MIDI keyboard, through a combination of receivemidi and sendmidi so I can spy on the traffic and use this wonderful swiss army knife to reverse engineer some sysex commands. I may be over-complicating this, so bear with me if there's a simpler solution.

Here's my proposed connection setup:

Windows Computer Running Proprietary Editor Software -> (LINUX with receivemidi (USB MIDI Device 1), data piped to sendmidi (USB MIDI DEVICE 2) ) -> Keyboard

And in reverse as well. This way my linux machine is in-between and can log the conversation, run scripts, etc. I really like this tool so trying to find a way...

This seems like it would work, however, the receivemidi/sendmidi only allow me to use device name, rather than an ID. Unfortunately, in my development setup, I have two MIDI usb devices that are the same make/model and same name:

Output from aplay -L

...
usbstream:CARD=S3
    Sound Blaster Play! 3
    USB Stream Output
sysdefault:CARD=Tab
    Default Audio Device
usbstream:CARD=Tab
    E-MU XMidi1X1 Tab
    USB Stream Output
sysdefault:CARD=Tab_1
    Default Audio Device
usbstream:CARD=Tab_1
    E-MU XMidi1X1 Tab
    USB Stream Output

Output from receivemidi list and sendmidi list:

Midi Through Port-0
E-MU XMidi1X1 Tab Out
E-MU XMidi1X1 Tab Out

I did try launching them successfully, hoping to get away with something, but it always selects the first device (although two instances can open the same card, which could be useful).

Is there a a way to use an index, or a flat out device id (ex: /dev/snd/midiC3D0)? I tried, but wasn't able to find a workaround. Maybe an option like receivemidi devindex 2 in my case? It would need to be checked each time because the cards can move around, but that would be really useful for some swiss army knife action using this tool.

From what I saw there weren't any good alsa tricks for this, so it seems like an index param in the tools would be a fairly easy feature to implement.

I know I can always find/buy/use a different midi device, but where's the fun in that? :)

Anyway, thanks for a great piece of software, I've used it on other projects and it came in super useful, especially the send clock features, that was a life-saver.

Timeout receivemidi

This is not an issue, but a request and I do not know how to contact you.

I am trying to connect to a MIDI device via a website server. The (private) server is connected to a midi device and I want to connect to it via a website page running on that server. I wrote a PHP script to handle the request. At first I used amidi, but that outputs unreliably. Then I used this software, sendmidi and recveivemidi. When I start the PHP script from the commandline (logged in via SSH) everything works fine. The receivemidi command does not terminate itself, so I programmed a timeout in my php script to terminate upon reception of a certain expected number of bytes or after (e.g.) 1 second. This seems to work.
However, when I access the PHP script from a remote website, the script ´hangs´ It will not terminate with a proc_terminate command as it does when I directly run the PHP from the server. I am struggling for 2 days now, it must have something todo with user rights. The apache error log shows
"Home directory not accessible: Permission denied", from which the origin I cannot find. Searching the web points to pulseaudio, but I am not sure and several attempts with user rights did not help.

Would it be possible to add some functionality in the receivemidi program to terminate upon reception of a certain number of bytes AND have a timeout?

Middle C displayed as C5

The note names in Note On and Off messages are from C0 to G10, middle C on a keyboard is usually named C3 or C4 and therefore the start note is C-2 or C-1
so it would be useful an option to choose the Middle C value between the aforementioned notes and choose one of them as default instead of displaying C5 when playing middle C.

spy on midi out ports

Hi,
first of all: thank you for saving me ages of coding time, I was missing a unix type commandline midi monitor utility and was thinking about creating one myself in python or something. Fortunately your tool already exists and is almost exactely what I was looking for! It probably would have taken me years to complete haha ;-)

One thing that I am missing is a feature that I know from snoize MIDI Monitor. You can monitor what goes into an actual midi output port. You probably know MIDI Monitor, it's called "spy on output to destinations" in the gui.

For instance sometimes I work with midi manipulator tools like "MIDIpipe". I would like to see what goes into midi pipe from my daw (Output Port: MidiPipe Input 1), and see what comes out after midi pipe (Input Port: MidiPipe Output 1).

Or another usecase was when I wanted to proof that a cheap china usb midi adapter does not transmit all midi data, it looses some ;-)

Is there any way this would be possible with receivemidi, maybe in combination with sendmidi or something?
Hope this all makes sense.

Thanks again!
all the best
Jojo

Receive multiple SysEx messages under Windows?

I'm trying to send a sequence of 16 SysEx messages from a device to ReceiveMIDI, and when I initiate the transfer I can only receive the first message using Windows. The Mac version works perfectly.

Mac output: (expected behaviour)
Mac-mini-3:~ matthew$ /Users/matthew/Downloads/receivemidi-macos-1.0.5/receivemidi dev Alex system-exclusive hex 00 02 17 0A 00 41 42 31 7E 34 4E 42 68 7F 7F 7F 7F 7F 7F 3F 3F 0A 01 00 0C 00 05 00 dec system-exclusive hex 00 02 17 0A 01 3D 7E 2F 7E 6A 6A 4B 07 7F 7F 7F 7F 7F 7F 3F 3F 0B 08 00 0C 00 01 00 dec system-exclusive hex 00 02 17 0A 02 1D 7F 5A 7F 26 25 7F 62 7F 7F 7F 7F 7F 7F 3F 3F 0B 03 00 0C 00 02 00 dec system-exclusive hex 00 02 17 0A 03 2E 4D 16 7F 40 58 7F 4D 7F 7F 7F 7F 7F 7F 3F 3F 08 00 00 0C 00 03 00 dec system-exclusive hex 00 02 17 0A 04 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 04 00 dec system-exclusive hex 00 02 17 0A 05 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 05 00 dec system-exclusive hex 00 02 17 0A 06 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 00 00 dec system-exclusive hex 00 02 17 0A 07 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 01 00 dec system-exclusive hex 00 02 17 0A 08 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 02 00 dec system-exclusive hex 00 02 17 0A 09 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 03 00 dec system-exclusive hex 00 02 17 0A 0A 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 04 00 dec system-exclusive hex 00 02 17 0A 0B 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 05 00 dec system-exclusive hex 00 02 17 0A 0C 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 00 00 dec system-exclusive hex 00 02 17 0A 0D 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 01 00 dec system-exclusive hex 00 02 17 0A 0E 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 02 00 dec system-exclusive hex 00 02 17 0A 0F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3F 3F 00 00 00 0C 00 03 00 dec

Windows output:
C:\Users\User\Desktop\receivemidi dev Alex system-exclusive hex 00 02 17 0A 00 41 42 31 7E 34 4E 42 68 7F 7F 7F 7F 7F 7F 3F 3F 0A 01 00 0C 00 05 00 dec

I am seeing the same kind of behaviour with other Windows MIDI apps including MIDI-OX. The sending device literally just sends the SysEx bytes, flushes the USB interface, then sends again, once per message until it's done.

I'm expecting to see the Mac output, 16 messages in a row.

Additionally - how hard would it be to dump the incoming SysEx messages to a .syx file?

Don't force march in the buildsystem

The buildsystem enforces -mtune=core2 -march=core2, which are valid only for x86 platforms.
I successfully built and used extensively on an arm cpu, you just have to remove those two flags.
Please edit your makefile to set them only on x86 platforms.

Execute Shell Script

Hi,

Thanks for a great project.
Any chance of modifying jsf, or rather adding an option to execute a shell script/command for each message?

Thanks!

MIDI Output shown instead

First of all I want to thank you for this great utility! The versatility is excellent and I'm using it for a custom controller script as we speak. While working with it earlier, I've noticed the list shows outputs instead of inputs. Typing the correct input port works however.

for (auto&& device : MidiOutput::getAvailableDevices())

does util.command work on windows?

Hi,

I am getting xxxx could not be started. This is on win7. I have tried using an absolute path and just the name of the command, e.g blah.exe.

Mike

Dependencies for Ubuntu

Hello,

Not sure if this is the right place to put this, but there are a few dependencies for compiling on Ubuntu that aren't listed or obvious:

pkg-config
libasound2-dev
libcurl4-openssl-dev

I assume this applies to SendMIDI too. Thanks for the software!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.