13
0

LuaProc: add option to set time information

This commit is contained in:
Robin Gareus 2023-06-18 22:39:45 +02:00
parent 1b6ba4d71d
commit 34789ff22f
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 107 additions and 1 deletions

View File

@ -157,6 +157,7 @@ private:
bool _lua_does_channelmapping;
bool _lua_has_inline_display;
bool _connect_all_audio_outputs;
bool _set_time_info;
void queue_draw () { QueueDraw(); /* EMIT SIGNAL */ }
DSP::DspShm lshm;

View File

@ -61,6 +61,7 @@ LuaProc::LuaProc (AudioEngine& engine,
, _lua_does_channelmapping (false)
, _lua_has_inline_display (false)
, _connect_all_audio_outputs (false)
, _set_time_info (false)
, _designated_bypass_port (UINT32_MAX)
, _signal_latency (0)
, _control_data (0)
@ -286,6 +287,26 @@ LuaProc::load_script ()
}
}
/* parse options */
luabridge::LuaRef options = luabridge::getGlobal (L, "dsp_options");
if (options.isFunction ()) {
try {
luabridge::LuaRef opts = options ();
if (opts.isTable ()) {
for (luabridge::Iterator i (opts); !i.isNil (); ++i) {
if (!i.key().isString()) {
continue;
}
if (i.key().cast<std::string> () == "time_info" && i.value().isBoolean ()) {
_set_time_info = i.value().cast<bool> ();
}
}
}
} catch (...) {
return true;
}
}
// initialize the DSP if needed
luabridge::LuaRef lua_dsp_init = luabridge::getGlobal (L, "dsp_init");
if (lua_dsp_init.type () == LUA_TFUNCTION) {
@ -678,6 +699,47 @@ LuaProc::connect_and_run (BufferSet& bufs,
#endif
try {
lua_State* L = lua.getState ();
if (_set_time_info) {
using namespace Temporal;
TempoMap::SharedPtr tmap (TempoMap::use ());
const TempoMetric& metric (tmap->metric_at (timepos_t (start)));
const TempoMetric& metric_end (tmap->metric_at (timepos_t (end)));
const BBT_Time& bbt (metric.bbt_at (timepos_t (start)));
luabridge::LuaRef lua_time (luabridge::newTable (L));
lua_time["sampleTime"] = start;
lua_time["sampleTimeEnd"] = end;
lua_time["tempo"] = metric.tempo ().quarter_notes_per_minute ();
lua_time["tempoEnd"] = metric_end.tempo ().quarter_notes_per_minute ();
lua_time["musicTime"] = DoubleableBeats (metric.tempo ().quarters_at_sample (start)).to_double ();
lua_time["musicTimeEnd"] = DoubleableBeats (metric_end.tempo ().quarters_at_sample (end)).to_double ();
lua_time["barPositionMusic"] = bbt.bars * 4;
lua_time["timeSigNumerator"] = metric.meter ().divisions_per_bar ();
lua_time["timeSigDenominator"] = metric.meter ().note_value ();
lua_time["TCframesPerSecond"] = _session.timecode_frames_per_second ();
lua_time["TCdropFrames"] = _session.timecode_drop_frames ();
if (_session.get_play_loop ()) {
Location* looploc = _session.locations ()->auto_loop_location ();
lua_time["looping"] = true;
lua_time["loopStart"] = looploc->start ().samples ();
lua_time["loopEnd"] = looploc->end ().samples ();
lua_time["loopStartMusic"] = DoubleableBeats (tmap->quarters_at (looploc->start ())).to_double ();
lua_time["loopEndMusic"] = DoubleableBeats (tmap->quarters_at (looploc->end ())).to_double ();
} else {
lua_time["looping"] = false;
}
luabridge::push (L, lua_time);
lua_setglobal (L, "time");
}
if (_lua_does_channelmapping) {
// run the DSP function
(*_lua_dsp)(&bufs, &in, &out, nframes, offset);
@ -686,7 +748,6 @@ LuaProc::connect_and_run (BufferSet& bufs,
BufferSet& silent_bufs = _session.get_silent_buffers (ChanCount (DataType::AUDIO, 1));
BufferSet& scratch_bufs = _session.get_scratch_buffers (ChanCount (DataType::AUDIO, 1));
lua_State* L = lua.getState ();
luabridge::LuaRef in_map (luabridge::newTable (L));
luabridge::LuaRef out_map (luabridge::newTable (L));

View File

@ -0,0 +1,44 @@
ardour {
["type"] = "dsp",
name = "Time Info",
category = "Utility",
author = "Ardour Team",
license = "MIT",
description = [[Example to use processing time info]]
}
function dsp_ioconfig ()
return { { midi_in = 1, midi_out = 1, audio_in = -1, audio_out = -1}, }
end
function dsp_options ()
return { time_info = true }
end
function dsp_run (_, _, n_samples)
assert (type(midiout) == "table")
assert (type(time) == "table")
assert (type(midiout) == "table")
local cnt = 1;
function tx_midi (time, data)
midiout[cnt] = {}
midiout[cnt]["time"] = time;
midiout[cnt]["data"] = data;
cnt = cnt + 1;
end
-- printing from rt-context is not thread-safe
print ("---")
for k,v in pairs (time) do
print (k, v);
end
-- pass-thru MIDI
for _,b in pairs (midiin) do
local t = b["time"] -- t = [ 1 .. n_samples ]
local d = b["data"] -- midi-event data
tx_midi (t, d)
end
end