--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/relpipe-data/examples-jack-midi-monitoring.xml Thu May 21 01:23:23 2020 +0200
@@ -0,0 +1,188 @@
+<stránka
+ xmlns="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana"
+ xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro">
+
+ <nadpis>Monitoring MIDI messages using JACK</nadpis>
+ <perex>examine events running through a JACK pipeline or bind MIDI keys to actions + bonus: Roland MT-32</perex>
+ <m:pořadí-příkladu>04100</m:pořadí-příkladu>
+
+ <text xmlns="http://www.w3.org/1999/xhtml">
+
+ <p>
+ A powerful audio system called <a href="https://jackaudio.org/">JACK</a> allows us to
+ build pipelines consisting of audio interfaces, players, recorders, filters and effects…
+ and route sound streams (both PCM and MIDI) through them.
+ MIDI messages can come from keyboards or other hardware MIDI controllers or from MIDI players and other software.
+ Sometimes it is useful to check what is happening under the hood and examine particular MIDI messages
+ instead of just playing them on a sound module or synthesizer.
+ In this example we will show how to bridge two seemingly unrelated worlds: real-time audio and relational pipes.
+ </p>
+
+ <p>
+ We can join the JACK graph with <code>relpipe-in-jack</code> command.
+ It does not consume STDIN, it gets events from JACK instead, so no other input data are needed.
+ </p>
+
+ <m:pre jazyk="bash">relpipe-in-jack | relpipe-out-gui</m:pre>
+
+ <p>
+ We are connected to the JACK daemon now, but no data are routed to us.
+ So we need to direct some MIDI streams to our input:
+ </p>
+
+ <m:img src="img/jack-connections-1.png"/>
+
+ <p>
+ And then incoming MIDI events will generate output like this:
+ </p>
+
+ <pre><![CDATA["event","channel","note_on","note_pitch","note_velocity","controller_id","controller_value","raw"
+"note","0","true","43","64","0","0","90 2b 40"
+"note","0","false","43","64","0","0","80 2b 40"
+"note","0","true","50","64","0","0","90 32 40"
+"note","0","false","50","64","0","0","80 32 40"
+"note","0","true","67","64","0","0","90 43 40"
+"note","0","false","67","64","0","0","80 43 40"
+"control","0","false","0","0","32","1","b0 20 01"
+"control","0","false","0","0","0","0","b0 00 00"
+"unknown","0","false","0","0","0","0","c0 00"
+"note","0","true","36","64","0","0","90 24 40"
+"note","0","false","36","64","0","0","80 24 40"
+"sysex","0","false","0","0","0","0","f0 41 10 16 12 20 00 00 61 68 6f 6a 3e f7"
+"note","0","true","60","64","0","0","90 3c 40"
+"note","0","false","60","64","0","0","80 3c 40"]]></pre>
+
+ <p>
+ CSV is not the only option. Once data are in the machine-readable relational format,
+ we can convert them into any other format or process them using any relational transformation.
+ For ad-hoc monitoring, we can use <code>relpipe-out-gui</code> and watch MIDI messages – as they come –
+ in a table in GUI:
+ </p>
+
+ <m:img src="img/jack-monitoring-gui-1.png"/>
+
+ <p>
+ As we can see, there are raw MIDI data and also some decoded values.
+ Future versions of <code>relpipe-in-jack</code> should provide improved decoder and other features like timing information.
+ </p>
+
+ <p>
+ We can use <code>relpipe-in-jack</code> not only for monitoring
+ but we can also write a simple script that binds particular MIDI events
+ to actions to be executed – like starting a program or running a script on background.
+ So we can map some keys/buttons/knobs on our piano, mixer or other controller:
+ </p>
+
+ <m:pre jazyk="bash"><![CDATA[#!/bin/bash
+
+read_nullbyte() { local IFS=; for v in "$@"; do export "$v"; read -r -d '' "$v"; done }
+
+relpipe-in-jack \
+ | relpipe-out-nullbyte \
+ | while read_nullbyte event channel note_on note_pitch velocity c_id c_value raw; do
+ if [[ "$note_pitch" == "21" && "$note_on" == "true" ]]; then kcalc &
+ elif [[ "$note_pitch" == "23" && "$note_on" == "true" ]]; then dolphin &
+ fi
+ done]]></m:pre>
+
+ <p>
+ Many audio applications have similar feature,
+ but we can leave this script running on the background
+ even when we do not want to have loaded a complex software like a DAW (Digital audio workstation).
+ </p>
+
+
+ <h2>Bonus: display messages on Roland MT-32</h2>
+
+ <p>
+ Maybe you remember games or MIDI files that <i>magically</i> displayed text messages on your
+ <a href="https://en.wikipedia.org/wiki/Roland_MT-32">MT-32</a> unit
+ which you used to generate wonderful sounds and music from the MIDI signal.
+ Let us look inside and check how this <i>magic</i> works.
+ </p>
+
+ <p>
+ We have to route the MIDI signal through JACK and fork it there (similarly to <code>tee</code> in shell)
+ so it will flow both to the MT-32 and the <code>relpipe-in-jack</code> process.
+ </p>
+
+ <p>
+ Given that we have running the JACK daemon (can be started from GUI application like QjackCtl)
+ and <code>a2j</code> which bridges ALSA-MIDI and JACK-MIDI together.
+ We set up the routing (the fork) and then play a SMF (Standard MIDI file) file:
+ </p>
+
+ <pre>aplaymidi --port=14:0 test.mid</pre>
+
+ <p>Proper port number could be found here:</p>
+
+ <pre><![CDATA[$ aplaymidi -l
+ Port Client name Port name
+ 14:0 Midi Through Midi Through Port-0
+ 24:0 Rubix44 Rubix44 MIDI 1]]></pre>
+
+ <p>
+ Data sent to the <i>Midi Through</i> port in the ALSA-MIDI emerges in the <code>a2j</code> in the JACK-MIDI graph
+ and then flows to <code>relpipe-in-jack</code>.
+ So the MT-32 will play the sounds and display messages (if any) and we will get copy of everything in
+ <code>relpipe-in-jack</code> that passes data to command like <code>relpipe-out-gui</code>
+ or <code>relpipe-out-csv</code> where we see decoded messages and also raw MIDI data.
+ </p>
+
+ <p>
+ n.b. the <i>Midi Through</i> in the ALSA-MIDI graph should be connected to our audio interface
+ (e.g. <a href="https://blog.frantovo.cz/c/365/Roland%20Rubix44%20%E2%80%93%20extern%C3%AD%20zvukov%C3%A1%20karta">Rubix44</a>)
+ which is linked to the MT-32 using a MIDI cable.
+ </p>
+
+ <p>
+ Messages that cause text to be showed on the MT-32 display are so called <i>System Exclusive (SysEx) messages</i>.
+ After executing the <code>aplaymidi</code> we see for example:
+ </p>
+
+ <m:img src="img/mt-32-display-1.jpeg"/>
+
+ <p>
+ And <code>relpipe-in-jack</code> captured and reported this SysEx message:
+ </p>
+
+ <pre>f0 41 10 16 12 20 00 00 <strong>52 65 6c 61 74 69 6f 6e 61 6c 20 70 69 70 65 73</strong> 14 f7</pre>
+
+ <p>
+ The highlighted part (52 … 73) is easy – it is just the <code>Relational pipes</code> ASCII bytes in HEX.
+ But what does the rest mean?
+ </p>
+
+ <ul>
+ <li><code>f0</code> = start of SysEx message</li>
+ <li><code>41</code> = Roland <a href="https://www.midi.org/specifications-old/item/manufacturer-id-numbers">manufacturer ID</a>. This is important because SysEx messages are vendor-specific. So devices from other manufacturers (that might be in the same MIDI daisy-chain) will know, that this message is not for them and will ignore it.</li>
+ <li><code>10</code> = device ID – if we have more units with same manufacturer and model ID, we should assign them different device IDs, so we can address them individually.</li>
+ <li><code>16</code> = model ID</li>
+ <li><code>12</code> = command ID, 12 is set, 11 is get</li>
+ <li><code>20 00 00</code> = the address of the value we want to set, 20 00 00 is the text to be displayed</li>
+ <li><code>14</code> = checksum computed from the <code>20 00 00 … 73</code> part</li>
+ <li><code>f7</code> = end of the SysEx message</li>
+ </ul>
+
+ <p>
+ Only the start and end of the SysEx message and the manufacturer ID are part of the MIDI standard.
+ The rest of the bytes is Roland specific. SysEx messages can do much more than controlling the display – consult the documentation for particular device.
+ </p>
+
+
+ <p>
+ We can generate our own messages using the <a href="https://hg.frantovo.cz/midi/mt-32-display/">mt-32-display</a> tool.
+ It produces SysEx messages for Roland MT-32 in hex format which can be passed directly to the <code>amidi</code> command (see examples in the code).
+ Unfortunately <code>amidi</code> works only with hardware ports and is unable to route through JACK.
+ But there is another tool called <a href="https://hg.frantovo.cz/midi/sysex2smf/">sysex2smf</a>
+ which translates raw SysEx data to Standard MIDI file (<code>*.mid</code>).
+ And SMF can be played using the <code>aplaymidi</code> which can be routed through JACK and our pipelines.
+ So the 48 lines of C++ code (both tools together) is everything we need to enjoy this nice feature of our MT-32 unit.
+ </p>
+
+ <video src="https://blog.frantovo.cz/s/1581/mt-32.webm" poster="img/mt-32-video-1.jpeg" controls="controls" width="820px">Maybe you often ask: What would MT-32 do?</video>
+
+
+ </text>
+
+</stránka>