--- /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>