relpipe-data/examples-jack-midi-monitoring.xml
branchv_0
changeset 296 418e11eb6fea
child 297 192b0059a6c4
equal deleted inserted replaced
295:72dc2469c438 296:418e11eb6fea
       
     1 <stránka
       
     2 	xmlns="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana"
       
     3 	xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro">
       
     4 	
       
     5 	<nadpis>Monitoring MIDI messages using JACK</nadpis>
       
     6 	<perex>examine events running through a JACK pipeline or bind MIDI keys to actions + bonus: Roland MT-32</perex>
       
     7 	<m:pořadí-příkladu>04100</m:pořadí-příkladu>
       
     8 
       
     9 	<text xmlns="http://www.w3.org/1999/xhtml">
       
    10 		
       
    11 		<p>
       
    12 			A powerful audio system called <a href="https://jackaudio.org/">JACK</a> allows us to
       
    13 			build pipelines consisting of audio interfaces, players, recorders, filters and effects…
       
    14 			and route sound streams (both PCM and MIDI) through them.
       
    15 			MIDI messages can come from keyboards or other hardware MIDI controllers or from MIDI players and other software.
       
    16 			Sometimes it is useful to check what is happening under the hood and examine particular MIDI messages
       
    17 			instead of just playing them on a sound module or synthesizer.
       
    18 			In this example we will show how to bridge two seemingly unrelated worlds: real-time audio and relational pipes.
       
    19 		</p>
       
    20 		
       
    21 		<p>
       
    22 			We can join the JACK graph with <code>relpipe-in-jack</code> command.
       
    23 			It does not consume STDIN, it gets events from JACK instead, so no other input data are needed.
       
    24 		</p>
       
    25 		
       
    26 		<m:pre jazyk="bash">relpipe-in-jack | relpipe-out-gui</m:pre>
       
    27 		
       
    28 		<p>
       
    29 			We are connected to the JACK daemon now, but no data are routed to us.
       
    30 			So we need to direct some MIDI streams to our input:
       
    31 		</p>
       
    32 		
       
    33 		<m:img src="img/jack-connections-1.png"/>
       
    34 		
       
    35 		<p>
       
    36 			And then incoming MIDI events will generate output like this:
       
    37 		</p>
       
    38 		
       
    39 		<pre><![CDATA["event","channel","note_on","note_pitch","note_velocity","controller_id","controller_value","raw"
       
    40 "note","0","true","43","64","0","0","90 2b 40"
       
    41 "note","0","false","43","64","0","0","80 2b 40"
       
    42 "note","0","true","50","64","0","0","90 32 40"
       
    43 "note","0","false","50","64","0","0","80 32 40"
       
    44 "note","0","true","67","64","0","0","90 43 40"
       
    45 "note","0","false","67","64","0","0","80 43 40"
       
    46 "control","0","false","0","0","32","1","b0 20 01"
       
    47 "control","0","false","0","0","0","0","b0 00 00"
       
    48 "unknown","0","false","0","0","0","0","c0 00"
       
    49 "note","0","true","36","64","0","0","90 24 40"
       
    50 "note","0","false","36","64","0","0","80 24 40"
       
    51 "sysex","0","false","0","0","0","0","f0 41 10 16 12 20 00 00 61 68 6f 6a 3e f7"
       
    52 "note","0","true","60","64","0","0","90 3c 40"
       
    53 "note","0","false","60","64","0","0","80 3c 40"]]></pre>
       
    54 		
       
    55 		<p>
       
    56 			CSV is not the only option. Once data are in the machine-readable relational format,
       
    57 			we can convert them into any other format or process them using any relational transformation.
       
    58 			For ad-hoc monitoring, we can use <code>relpipe-out-gui</code> and watch MIDI messages – as they come –
       
    59 			in a table in GUI:
       
    60 		</p>
       
    61 		
       
    62 		<m:img src="img/jack-monitoring-gui-1.png"/>
       
    63 		
       
    64 		<p>
       
    65 			As we can see, there are raw MIDI data and also some decoded values.
       
    66 			Future versions of <code>relpipe-in-jack</code> should provide improved decoder and other features like timing information.
       
    67 		</p>
       
    68 		
       
    69 		<p>
       
    70 			We can use <code>relpipe-in-jack</code> not only for monitoring 
       
    71 			but we can also write a simple script that binds particular MIDI events
       
    72 			to actions to be executed – like starting a program or running a script on background.
       
    73 			So we can map some keys/buttons/knobs on our piano, mixer or other controller:
       
    74 		</p>
       
    75 		
       
    76 		<m:pre jazyk="bash"><![CDATA[#!/bin/bash
       
    77 
       
    78 read_nullbyte() { local IFS=; for v in "$@"; do export "$v"; read -r -d '' "$v"; done }
       
    79 
       
    80 relpipe-in-jack \
       
    81 	| relpipe-out-nullbyte \
       
    82 	| while read_nullbyte event channel note_on note_pitch velocity c_id c_value raw; do
       
    83 		if   [[ "$note_pitch" == "21" && "$note_on" == "true" ]]; then kcalc &
       
    84 		elif [[ "$note_pitch" == "23" && "$note_on" == "true" ]]; then dolphin &
       
    85 		fi
       
    86 	done]]></m:pre>
       
    87 		
       
    88 		<p>
       
    89 			Many audio applications have similar feature, 
       
    90 			but we can leave this script running on the background 
       
    91 			even when we do not want to have loaded a complex software like a DAW (Digital audio workstation).
       
    92 		</p>
       
    93 		
       
    94 		
       
    95 		<h2>Bonus: display messages on Roland MT-32</h2>
       
    96 		
       
    97 		<p>
       
    98 			Maybe you remember games or MIDI files that <i>magically</i> displayed text messages on your 
       
    99 			<a href="https://en.wikipedia.org/wiki/Roland_MT-32">MT-32</a> unit 
       
   100 			which you used to generate wonderful sounds and music from the MIDI signal.
       
   101 			Let us look inside and check how this <i>magic</i> works.
       
   102 		</p>
       
   103 		
       
   104 		<p>
       
   105 			We have to route the MIDI signal through JACK and fork it there (similarly to <code>tee</code> in shell)
       
   106 			so it will flow both to the MT-32 and the <code>relpipe-in-jack</code> process.
       
   107 		</p>
       
   108 		
       
   109 		<p>
       
   110 			Given that we have running the JACK daemon (can be started from GUI application like QjackCtl)
       
   111 			and <code>a2j</code> which bridges ALSA-MIDI and JACK-MIDI together.
       
   112 			We set up the routing (the fork) and then play a SMF (Standard MIDI file) file:
       
   113 		</p>
       
   114 		
       
   115 		<pre>aplaymidi --port=14:0 test.mid</pre>
       
   116 		
       
   117 		<p>Proper port number could be found here:</p>
       
   118 		
       
   119 		<pre><![CDATA[$ aplaymidi -l
       
   120  Port    Client name                      Port name
       
   121  14:0    Midi Through                     Midi Through Port-0
       
   122  24:0    Rubix44                          Rubix44 MIDI 1]]></pre>
       
   123  
       
   124 		<p>
       
   125 			Data sent to the <i>Midi Through</i> port in the ALSA-MIDI emerges in the <code>a2j</code> in the JACK-MIDI graph
       
   126 			and then flows to <code>relpipe-in-jack</code>.
       
   127 			So the MT-32 will play the sounds and display messages (if any) and we will get copy of everything in
       
   128 			<code>relpipe-in-jack</code> that passes data to command like <code>relpipe-out-gui</code>
       
   129 			or <code>relpipe-out-csv</code> where we see decoded messages and also raw MIDI data.
       
   130 		</p>
       
   131 		
       
   132 		<p>
       
   133 			n.b. the <i>Midi Through</i> in the ALSA-MIDI graph should be connected to our audio interface 
       
   134 			(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>)
       
   135 			which is linked to the MT-32 using a MIDI cable.
       
   136 		</p>
       
   137 	
       
   138 		<p>
       
   139 			Messages that cause text to be showed on the MT-32 display are so called <i>System Exclusive (SysEx) messages</i>.
       
   140 			After executing the <code>aplaymidi</code> we see for example:
       
   141 		</p>
       
   142 		
       
   143 		<m:img src="img/mt-32-display-1.jpeg"/>
       
   144 		
       
   145 		<p>
       
   146 			And <code>relpipe-in-jack</code> captured and reported this SysEx message:
       
   147 		</p>
       
   148 		
       
   149 		<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>
       
   150 		
       
   151 		<p>
       
   152 			The highlighted part (52 … 73) is easy – it is just the <code>Relational pipes</code> ASCII bytes in HEX.
       
   153 			But what does the rest mean?
       
   154 		</p>
       
   155 		
       
   156 		<ul>
       
   157 			<li><code>f0</code> = start of SysEx message</li>
       
   158 			<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>
       
   159 			<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>
       
   160 			<li><code>16</code> = model ID</li>
       
   161 			<li><code>12</code> = command ID, 12 is set, 11 is get</li>
       
   162 			<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>
       
   163 			<li><code>14</code> = checksum computed from the <code>20 00 00 … 73</code> part</li>
       
   164 			<li><code>f7</code> = end of the SysEx message</li>
       
   165 		</ul>
       
   166 		
       
   167 		<p>
       
   168 			Only the start and end of the SysEx message and the manufacturer ID are part of the MIDI standard.
       
   169 			The rest of the bytes is Roland specific. SysEx messages can do much more than controlling the display – consult the documentation for particular device.
       
   170 		</p>
       
   171 		
       
   172 	
       
   173 		<p>
       
   174 			We can generate our own messages using the <a href="https://hg.frantovo.cz/midi/mt-32-display/">mt-32-display</a> tool.
       
   175 			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).
       
   176 			Unfortunately <code>amidi</code> works only with hardware ports and is unable to route through JACK.
       
   177 			But there is another tool called <a href="https://hg.frantovo.cz/midi/sysex2smf/">sysex2smf</a>
       
   178 			which translates raw SysEx data to Standard MIDI file (<code>*.mid</code>).
       
   179 			And SMF can be played using the <code>aplaymidi</code> which can be routed through JACK and our pipelines.
       
   180 			So the 48 lines of C++ code (both tools together) is everything we need to enjoy this nice feature of our MT-32 unit.
       
   181 		</p>
       
   182 
       
   183 		<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>
       
   184 		
       
   185 		
       
   186 	</text>
       
   187 
       
   188 </stránka>