Skip to content

Commit cf646c9

Browse files
chore: autopublish 2023-11-30T15:23:45Z
1 parent 77b7772 commit cf646c9

File tree

6 files changed

+428
-156
lines changed

6 files changed

+428
-156
lines changed

dist/go_to_time.lua

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
function plugindef()
2+
finaleplugin.RequireSelection = false
3+
finaleplugin.Author = "Carl Vine"
4+
finaleplugin.AuthorURL = "https://carlvine.com/lua/"
5+
finaleplugin.Copyright = "CC0 https://creativecommons.org/publicdomain/zero/1.0/"
6+
finaleplugin.Version = "0.05"
7+
finaleplugin.Date = "2023/11/21"
8+
finaleplugin.CategoryTags = "Measures, Region, Selection"
9+
finaleplugin.MinJWLuaVersion = 0.62
10+
finaleplugin.Notes = [[
11+
To navigate to a specific time in the current file,
12+
enter the minutes and seconds in duration.
13+
Either value can include decimal points.
14+
Accelerandos and Rallentandos are not considered and only the
15+
first tempo mark in each measure is evaluated.
16+
These are assumed to take effect at the start of that measure.
17+
]]
18+
finaleplugin.HashURL = "https://raw.githubusercontent.com/finale-lua/lua-scripts/master/hash/go_to_time.hash"
19+
return "Go To Time...", "Go To Time", "Navigate to a specific time in the current file"
20+
end
21+
function get_new_tempo(measure, beat, speed)
22+
for expression in each(measure:CreateExpressions()) do
23+
local exp_def = expression:CreateTextExpressionDef()
24+
if exp_def and (exp_def:IsPlaybackTempo()
25+
or exp_def.PlaybackType == finale.EXPPLAYTYPE_TEMPO) then
26+
local b = exp_def:GetPlaybackTempoDuration()
27+
local s = exp_def:GetPlaybackTempoValue()
28+
if b > 0 and s > 0 then
29+
beat = b
30+
speed = s
31+
break
32+
end
33+
end
34+
end
35+
return beat, speed
36+
end
37+
local function choose_target_time()
38+
local s = finale.FCString()
39+
local function fs(str)
40+
s.LuaString = tostring(str)
41+
return s
42+
end
43+
local dialog = finale.FCCustomLuaWindow()
44+
local x, y = 60, 0
45+
dialog:SetTitle(fs(plugindef()))
46+
local stat = dialog:CreateStatic(0, y)
47+
stat:SetText(fs("Go to measure starting at:"))
48+
stat:SetWidth(150)
49+
y = y + 18
50+
local min = dialog:CreateEdit(0, y)
51+
min:SetWidth(x - 10)
52+
min:SetText(fs("0"))
53+
local sec = dialog:CreateEdit(x, y)
54+
sec:SetWidth(x - 10)
55+
sec:SetText(fs("0"))
56+
y = y + 20
57+
stat = dialog:CreateStatic(0, y)
58+
stat:SetText(fs("minutes"))
59+
stat:SetWidth(x)
60+
stat = dialog:CreateStatic(x, y)
61+
stat:SetText(fs("seconds"))
62+
stat:SetWidth(x)
63+
y = y + 20
64+
local select = dialog:CreateCheckbox(0, y)
65+
select:SetWidth(150)
66+
select:SetText(fs("select matching measure"))
67+
select:SetCheck(1)
68+
local but = dialog:CreateOkButton()
69+
but:SetText(fs("GO"))
70+
dialog:CreateCancelButton()
71+
local ok = (dialog:ExecuteModal(nil) == finale.EXECMODAL_OK)
72+
local s_min = finale.FCString()
73+
min:GetText(s_min)
74+
sec:GetText(s)
75+
local target = tonumber(s_min.LuaString) * 60 + tonumber(s.LuaString)
76+
return ok, target, (select:GetCheck() == 1)
77+
end
78+
local function move_to_target(rgn, match_measure, select)
79+
finenv.UI():MoveToMeasure(match_measure, 0)
80+
if select then
81+
rgn.StartMeasure = match_measure
82+
rgn.EndMeasure = match_measure
83+
rgn.StartSlot = 1
84+
rgn.EndSlot = 1
85+
rgn:SetInDocument()
86+
end
87+
end
88+
local function find_matching_measure()
89+
local measure = finale.FCMeasure()
90+
local rgn = finale.FCMusicRegion()
91+
rgn:SetFullDocument()
92+
93+
local pb_prefs = finale.FCPlaybackPrefs()
94+
pb_prefs:LoadFirst()
95+
local beat = pb_prefs.MetronomeBeat
96+
local speed = pb_prefs.MetronomeSpeed
97+
local ok, target, select = choose_target_time()
98+
if not ok then return end
99+
local tally = 0
100+
local match_measure = 0
101+
102+
for measure_num = 1, rgn.EndMeasure do
103+
if tally >= target then
104+
match_measure = measure_num
105+
break
106+
end
107+
108+
measure:Load(measure_num)
109+
beat, speed = get_new_tempo(measure, beat, speed)
110+
local m_duration = (measure:GetDuration() * 60) / (beat * speed)
111+
tally = tally + m_duration
112+
if tally > target then
113+
match_measure = measure_num
114+
break
115+
end
116+
end
117+
if match_measure > 0 then
118+
move_to_target(rgn, match_measure, select)
119+
else
120+
local min = math.floor(target / 60)
121+
local sec = target - (min * 60)
122+
local msg = "The nominated time of "
123+
.. string.format("[%02d:%05.2f]", min, sec)
124+
.. " is longer than the duration of the current score"
125+
finenv.UI():AlertInfo(msg, plugindef())
126+
end
127+
end
128+
find_matching_measure()

0 commit comments

Comments
 (0)