--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/relpipe-data/examples/jack-midi-1.sql Thu Oct 22 01:51:32 2020 +0200
@@ -0,0 +1,77 @@
+WITH
+ -- Configuration parameters:
+ duration AS (SELECT 16 AS value), -- in seconds
+ bpm AS (SELECT 120 AS value), -- beats per minute
+
+ -- Numbered beats, the outline:
+ beat AS (
+ WITH RECURSIVE beat0 AS (
+ SELECT 0 AS value
+ UNION ALL
+ SELECT beat0.value + 1 FROM beat0, duration, bpm
+ WHERE beat0.value < (duration.value * bpm.value / 60 - 1)
+ )
+ SELECT * FROM beat0
+ ),
+
+ -- Set instruments for particular channels:
+ raw AS (
+ SELECT 0 AS time, 'c0 0e' AS raw UNION ALL -- channel 1 = Tubular Bells
+ SELECT 0 AS time, 'c1 58' AS raw -- channel 2 = Fantasia
+ ),
+
+ -- Parts (quite random sounds):
+
+ drums_1 AS (
+ SELECT
+ 9 AS channel,
+ beat.value AS beat, NULL AS custom_time,
+ 250 * 1000 AS duration,
+ CASE WHEN beat.value % 4 IN (0,1,2) THEN 35 ELSE 40 END AS note_pitch,
+ 80 AS note_velocity
+ FROM beat, bpm
+ ),
+
+ bells_1 AS (
+ SELECT
+ 0 AS channel,
+ beat.value AS beat, NULL AS custom_time,
+ 500 * 1000 AS duration,
+ CASE WHEN beat.value / 4 % 2 = 0 THEN 68 ELSE 55 END AS note_pitch,
+ 90 AS note_velocity
+ FROM beat, bpm
+ WHERE beat.value % 4 IN (1)
+ ),
+
+ fantasia_1 AS (
+ SELECT
+ 1 AS channel,
+ beat.value AS beat, NULL AS custom_time,
+ 500 * 1000 AS duration,
+ 60 + beat.value % 4 AS note_pitch,
+ 90 AS note_velocity
+ FROM beat, bpm
+ WHERE beat.value % 4 IN (2,3,0)
+ ),
+
+ -- Put all parts together:
+ notes AS (
+ SELECT
+ part.*,
+ CASE
+ WHEN custom_time IS NULL THEN beat * 1000 * 1000 * 60 / bpm.value
+ ELSE CAST(custom_time AS integer)
+ END AS time
+ FROM (
+ SELECT * FROM drums_1 UNION ALL
+ SELECT * FROM bells_1 UNION ALL
+ SELECT * FROM fantasia_1
+ ) AS part, bpm
+ )
+
+-- We need to emit two MIDI events: one for key press and one for key release.
+-- So we add the release events (note_on = false) derived from the time and duration values.
+SELECT 'note' AS event, time, channel, 1 AS note_on, note_pitch, note_velocity, '' AS raw FROM notes UNION ALL
+SELECT 'note' AS event, time+duration AS time, channel, 0 AS note_on, note_pitch, note_velocity, '' AS raw FROM notes UNION ALL
+SELECT 'sysex' AS event, time, 0 AS channel, 0 AS note_on, 0 AS note_pitch, 0 AS note_velocity, raw FROM raw
+ORDER BY time ASC, event DESC;