Skip to content

Commit d445458

Browse files
authored
Merge pull request #1072 from Alexander-Zyurkalov/Flesh-Out-Timecode-Message-Factories-736
feat: add MTC message generation functions and a Lua script example
2 parents 49b588f + 66155f7 commit d445458

7 files changed

Lines changed: 783 additions & 4 deletions

File tree

scripts/mtc_generator.lua

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
--- MTC Generator.
2+
--
3+
-- Generates MIDI Timecode (MTC) based on the transport state.
4+
--
5+
-- @script mtc_generator
6+
-- @type DSP
7+
-- @license GPL v3
8+
-- @author Alexandr Zyurkalov
9+
10+
local MidiBuffer = require ('el.MidiBuffer')
11+
local midi = require ('el.midi')
12+
local bytes = require ('el.bytes')
13+
14+
-- Buffer to render filtered output
15+
local output = MidiBuffer.new ()
16+
17+
-- Transport state and buffer properties
18+
local wasPlaying = false
19+
local lastSamplePosition = -1
20+
local sampleRate = 44100.0
21+
local bufSize = 512
22+
local buffer = bytes.new (10)
23+
local framesPerSecond = 24
24+
25+
local function layout ()
26+
return {
27+
audio = { 0, 0 },
28+
midi = { 0, 1 }
29+
}
30+
end
31+
32+
-- prepare for rendering
33+
local function prepare (rate, block)
34+
-- reserve memory and clear the output buffer
35+
output:reserve (256)
36+
output:clear ()
37+
sampleRate = rate
38+
bufSize = block
39+
end
40+
41+
local function process (_, m, _, _, t)
42+
-- Get MIDI input buffer from the MidiPipe
43+
local input = m:get (1)
44+
45+
output:clear ()
46+
47+
local playing = t:playing ()
48+
local samplePosition = t:frame ()
49+
50+
local wasJumped = samplePosition ~= lastSamplePosition and lastSamplePosition >= 0
51+
if not playing and (wasPlaying or wasJumped) then
52+
local size = midi.mtcfullframetransport (buffer, samplePosition + bufSize - 1, sampleRate, framesPerSecond)
53+
output:insertBytes (buffer, size, bufSize)
54+
end
55+
56+
if playing then
57+
local msg, frame, sentMessages = 0
58+
59+
repeat
60+
sentMessages, msg, frame = midi.quarterframetransport (samplePosition, bufSize, sampleRate, framesPerSecond, sentMessages)
61+
output:insertPacked (msg, frame)
62+
until msg == nil
63+
end
64+
65+
wasPlaying = playing
66+
lastSamplePosition = samplePosition
67+
68+
-- DSP scripts use replace processing, so swap in the rendered output
69+
input:swap (output)
70+
end
71+
72+
return {
73+
type = 'DSP',
74+
layout = layout,
75+
prepare = prepare,
76+
process = process
77+
}
78+
79+
-- SPDX-FileCopyrightText: Copyright (C) Kushview, LLC.
80+
-- SPDX-License-Identifier: GPL-3.0-or-later

0 commit comments

Comments
 (0)