relpipe-data/examples/jack-midi-1.sql
branchv_0
changeset 317 fce3d6290c40
--- /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;