relpipe-data/examples-jack-midi-generating-1.xml
branchv_0
changeset 317 fce3d6290c40
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relpipe-data/examples-jack-midi-generating-1.xml	Thu Oct 22 01:51:32 2020 +0200
@@ -0,0 +1,398 @@
+<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>Generating and sending MIDI messages</nadpis>
+	<perex>generate some sounds and send them to the JACK daemon</perex>
+	<m:pořadí-příkladu>04500</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.
+		</p>
+		
+		<p>
+			While <code>relpipe-in-jack</code> can be used for <m:a href="examples-jack-midi-monitoring">monitoring MIDI messages</m:a> (<i>recording</i>),
+			the <code>relpipe-out-jack</code> (since <m:a href="release-v0.17">v0.17</m:a>) is designed for sending messages to JACK (<i>playback</i>).
+			So instead of playing <em>Standard MIDI Files</em> (.smf, .mid)
+			we can read relational data and send them as MIDI messages to JACK daemon that forwards them to a hardware or software synthesizer
+			or other program (called <i>client</i> in JACK terminology).
+		</p>
+		
+		<p>
+			The <code>relpipe-out-jack</code> reads relational data in the same format as <code>relpipe-in-jack</code>.
+			So we can capture some MIDI data and play it later.
+			But this is bit boring and any music sequencer would do a better job.
+			We can have more fun with programmatically generating the „music“ (or rather just sounds in beginnings).
+			Thanks to the nature of <m:name/>, the relation containing such „music“ can come from many various sources.
+			In this example we will use the SQL language.
+		</p>
+		
+		
+		<h2>Connect and say hello to MT-32 (SysEx)</h2>
+		
+		<p>
+			Before doing anything audible, we will start with saying hello to our sound module.
+			We need a relation with two attributes. The first one is <code>event</code> and says what should be done.
+			The second one <code>raw</code> contains the raw MIDI data. It is a SysEx message specific to Roland MT-32,
+			but it can be any MIDI event:
+		</p>
+		
+		<m:pre jazyk="bash"><![CDATA[relpipe-in-cli \
+	--relation "midi" \
+		--attribute "event" string \
+		--attribute "raw" string \
+		--record "sysex" "f0 41 10 16 12 20 00 00 52 65 6c 70 69 70 65 21 6e f7" \
+	| relpipe-out-jack --connect-to j2a_bridge:playback]]></m:pre>
+	
+		<p>
+			If we omit the <code>--connect-to j2a_bridge:playback</code> part, the <code>relpipe-out-jack</code> command
+			will wait util we connect it somewhere e.g. using QjackCtl.
+			We can control this behavior by explicitly specifying <code>--required-connections N</code> (default <code>N</code> is 1)
+			and say e.g. „Wait until you have 3 connections and then start sending“.
+			But because we specified the destination port, the <code>relpipe-out-jack</code> command immediately
+			connects to it and sends data there.
+		</p>
+		
+		<p>
+			The <code>j2a_bridge:playback</code> port was created by the <code>j2amidi_bridge</code>
+			that bridges JACK-MIDI and ALSA-MIDI.
+			In QjackCtl or other tool, we can connect the ALSA end of this bridge to a physical interface (sound module, synthesizer).
+			If we have no audio hardware, we omit this part and stay in the JACK world – we can connect our MIDI ports to various
+			applications like Yoshimi, QMidiArp, Qtractor etc.
+		</p>
+		
+		<p>
+			See more details on MT-32 and MIDI SysEx in: <m:a href="examples-jack-midi-monitoring">Monitoring MIDI messages using JACK</m:a>.
+		</p>
+		
+		<h2>Set the MIDI instruments for particular channels</h2>
+		
+		<p>
+			Instruments (like particular pianos, guitars, drums, special effects etc.) can be set on our synthesizer for particular channels.
+			However for reproducible results and more comfort, it is better to configure the instruments through MIDI commands (<i>Patch change</i>).
+			Currently we misuse the <code>sysex</code> event for this and send this configuration as raw MIDI commands
+			(the <code>c0 0e</code> and <code>c1 58</code> below).
+			In later versions of <code>relpipe-out-jack</code>, there might be better support for instrument configuration.
+		</p>
+		
+		<p>
+			The list of standard instruments is available at MIDI.org: <a href="https://www.midi.org/specifications/item/gm-level-1-sound-set">General MIDI: GM 1 Sound Set</a>.
+		</p>
+		
+		<h2>Play some SQL tones</h2>
+		
+		<p>
+			Specifying the notes as raw MIDI messages is possible but uncomfortable.
+			So we will put <code>note</code> in the <code>event</code> attribute
+			and specify also <code>time</code>, <code>channel</code>, <code>note_on</code>, <code>note_pitch</code> and <code>note_velocity</code> attributes.
+			The <code>relpipe-out-jack</code> will compose the raw MIDI event from these values.
+		</p>
+		
+		<p>
+			We are not going to create any tables or insert any records.
+			Everything in this example is done in-memory by a single SELECT statement executed on an empty database.
+			But of course, we can persist our creations in database tables and later play the music by SELECTing from them.
+		</p>
+		
+		<m:pre jazyk="sql" odkaz="ano" src="examples/jack-midi-1.sql"/>
+		
+		<p>
+			The SQL engine (SQLite by default) called from <code>relpipe-in-sql</code> converts our script into a relation.
+			Then the <code>relpipe-out-jack</code> translates this relation to actual MIDI events and sends them to JACK system.
+		</p>
+		
+		<m:pre jazyk="bash"><![CDATA[relpipe-in-sql \
+	--relation "midi" "$(cat examples/jack-midi-1.sql)" \
+	--type-cast 'note_on' boolean \
+	| relpipe-out-jack \
+		--connect-to j2a_bridge:playback \
+		--connect-to relpipe-in-jack:midi-in]]></m:pre>
+		
+		<p>
+			We connect it to two ports, so we can hear the sounds and at the same time, we can monitor the MIDI events
+			(through <code>relpipe-in-jack</code> and usually <code>relpipe-out-csv</code>).
+			We can also use <code>relpipe-out-tabular</code> instead of <code>relpipe-out-jack</code> and check generated data without sending them to JACK.
+			For visual check, we can connect to the JACK port of a MIDI program like Qtractor and record there our creation (like recording from a MIDI keyboard).
+			We can also do some real-time post-processing e.g. using QMidiArp (arpeggiator).
+		</p>
+		
+		<p>
+			If we have some hardware, it should look and sound like this:
+		</p>
+		
+		<video src="https://blog.frantovo.cz/s/1601/jack-midi-1.webm" poster="img/sc-88-video-1.jpeg" controls="controls" width="820px">Maybe you often ask: What would MT-32 do?</video>
+		
+		<p>
+			In this video, the Roland MT-32 and SC-88 Pro are daisy-chained and most sounds come from the SC-88.
+		</p>
+		
+		<p>
+			n.b. the MIDI channel 1 (index 0) is usually silent on MT-32 (default configuration).
+		</p>
+		
+		
+		
+		<h2>Supported event types and attributes</h2>
+		
+		<p>
+			The <code>relpipe-out-jack</code> supports following event types:
+		</p>
+		
+		<ul>
+			<li>
+				<code>note</code>: press or release (depending on <code>note_on</code>) of particular key on keyboard
+			</li>
+			<li>
+				<code>control</code>: change value of a controller (knob, slider, switch etc.)
+			</li>
+			<li>
+				<code>sysex</code>: SystemExclusive command specific for particular device or manufacturer (e.g. show some text on the display)
+			</li>
+			<li>
+				<code>connect</code>: link two JACK ports using a virtual cable
+			</li>
+			<li>
+				<code>disconnect</code>: put that cable away
+			</li>
+		</ul>
+		
+		<p>
+			Because the events of various types are usually interleaved, we pass them as records of one relation.
+			Each type uses a different set of attributes:
+		</p>
+		
+		<table>
+			<thead>
+				<tr>
+					<td><code>event</code></td>
+					<td><code>note</code></td>
+					<td><code>control</code></td>
+					<td><code>sysex</code></td>
+					<td><code>connect</code></td>
+					<td><code>disconnect</code></td>
+				</tr>
+			</thead>
+			<tbody>
+				<tr>
+					<td><code>time</code></td>
+					<td>✔</td>
+					<td>✔</td>
+					<td>✔</td>
+					<td></td>
+					<td></td>
+				</tr>
+				<tr>
+					<td><code>channel</code></td>
+					<td>✔</td>
+					<td>✔</td>
+					<td>✔</td>
+					<td></td>
+					<td></td>
+				</tr>
+				<tr>
+					<td><code>note_on</code></td>
+					<td>✔</td>
+					<td></td>
+					<td></td>
+					<td></td>
+					<td></td>
+				</tr>
+				<tr>
+					<td><code>note_pitch</code></td>
+					<td>✔</td>
+					<td></td>
+					<td></td>
+					<td></td>
+					<td></td>
+				</tr>
+				<tr>
+					<td><code>note_velocity</code></td>
+					<td>✔</td>
+					<td></td>
+					<td></td>
+					<td></td>
+					<td></td>
+				</tr>
+				<tr>
+					<td><code>controller_id</code></td>
+					<td></td>
+					<td>✔</td>
+					<td></td>
+					<td></td>
+					<td></td>
+				</tr>
+				<tr>
+					<td><code>controller_value</code></td>
+					<td></td>
+					<td>✔</td>
+					<td></td>
+					<td></td>
+					<td></td>
+				</tr>
+				<tr>
+					<td><code>raw</code></td>
+					<td></td>
+					<td></td>
+					<td>✔</td>
+					<td></td>
+					<td></td>
+				</tr>
+				<tr>
+					<td><code>source_port</code></td>
+					<td></td>
+					<td></td>
+					<td></td>
+					<td>✔</td>
+					<td>✔</td>
+				</tr>
+				<tr>
+					<td><code>destination_port</code></td>
+					<td></td>
+					<td></td>
+					<td></td>
+					<td>✔</td>
+					<td>✔</td>
+				</tr>
+			</tbody>
+		</table>
+		
+		
+		<p>
+			Note: this design pattern is one of possible ways how to implement the <em>inheritance</em> (an object-oriented concept) in the relational world.
+			The relation contains one attribute that determines the <i>type</i> (or <i>class</i>)
+			and then union of all attributes of all that types.
+			Each type uses just its relevant attributes and the rest is empty.
+		</p>
+		
+		<p>
+			The meaning of the attributes is following:
+		</p>
+		
+		<table>
+			<thead>
+				<tr>
+					<td>attribute</td>
+					<td>type</td>
+					<td>description</td>
+				</tr>
+			</thead>
+			<tbody>
+				<tr>
+					<td>
+						<code>event</code>
+					</td>
+					<td>
+						<code>string</code>
+					</td>
+					<td>type of the record</td>
+				</tr>
+				<tr>
+					<td>
+						<code>time</code>
+					</td>
+					<td>
+						<code>integer</code>
+					</td>
+					<td>time in microseconds since start of the playback</td>
+				</tr>
+				<tr>
+					<td>
+						<code>channel</code>
+					</td>
+					<td>
+						<code>integer</code>
+					</td>
+					<td>number of the MIDI channel; starts from 0</td>
+				</tr>
+				<tr>
+					<td>
+						<code>note_on</code>
+					</td>
+					<td>
+						<code>boolean</code>
+					</td>
+					<td>whether the key was pressed (<code>true</code>) or released (<code>false</code>)</td>
+				</tr>
+				<tr>
+					<td>
+						<code>note_pitch</code>
+					</td>
+					<td>
+						<code>integer</code>
+					</td>
+					<td>pitch or tone; starts from 0; e.g. C4 is 60</td>
+				</tr>
+				<tr>
+					<td>
+						<code>note_velocity</code>
+					</td>
+					<td>
+						<code>integer</code>
+					</td>
+					<td>force with which a note is played; 0-127</td>
+				</tr>
+				<tr>
+					<td>
+						<code>controller_id</code>
+					</td>
+					<td>
+						<code>integer</code>
+					</td>
+					<td>number of the controller; starts from 0</td>
+				</tr>
+				<tr>
+					<td>
+						<code>controller_value</code>
+					</td>
+					<td>
+						<code>integer</code>
+					</td>
+					<td>value of the controller; 0-127</td>
+				</tr>
+				<tr>
+					<td>
+						<code>raw</code>
+					</td>
+					<td>
+						<code>string</code>
+					</td>
+					<td>raw MIDI bytes written in hexadecimal format; e.g. <code>91 3c 41</code></td>
+				</tr>
+				<tr>
+					<td>
+						<code>source_port</code>
+					</td>
+					<td>
+						<code>string</code>
+					</td>
+					<td>name of the JACK output port; e.g. <code>system:capture_1</code></td>
+				</tr>
+				<tr>
+					<td>
+						<code>destination_port</code>
+					</td>
+					<td>
+						<code>string</code>
+					</td>
+					<td>name of the JACK input port; e.g. <code>system:playback_1</code></td>
+				</tr>
+			</tbody>
+		</table>
+		
+		<p>
+			Besides the <code>event</code> we need to specify only attributes we use.
+			So if we e.g. only send SysEx messages, we need only <code>event</code> and <code>raw</code> attributes.
+			If the <code>time</code> is missing, the event is processed as soon as possible (in the next real-time cycle).
+			The <code>time</code> attribute is used for precise timing 
+			– so the process is not driven by the time when the event arrives on STDIN of the <code>relpipe-out-jack</code>.
+		</p>
+		
+
+	</text>
+
+</stránka>