Skip to content

Commit 1c04983

Browse files
committed
Update midi_note_values.lua
script_name from general_library; keystroke filtering for simpler error checking; code optimisation; upgraded Notes for `utils.show_notes_dialog`;
1 parent 38e74a5 commit 1c04983

File tree

1 file changed

+97
-87
lines changed

1 file changed

+97
-87
lines changed

src/midi_note_values.lua

+97-87
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ function plugindef()
33
finaleplugin.Author = "Carl Vine"
44
finaleplugin.AuthorURL = "http://carlvine.com/lua/"
55
finaleplugin.Copyright = "https://creativecommons.org/licenses/by/4.0/"
6-
finaleplugin.Version = "v0.13"
7-
finaleplugin.Date = "2023/04/07"
6+
finaleplugin.Version = "0.22"
7+
finaleplugin.Date = "2024/02/03"
88
finaleplugin.CategoryTags = "MIDI"
9-
finaleplugin.MinJWLuaVersion = 0.63
9+
finaleplugin.MinJWLuaVersion = 0.70
1010
finaleplugin.AdditionalMenuOptions = [[
1111
MIDI Note Duration...
1212
MIDI Note Velocity...
@@ -16,35 +16,48 @@ function plugindef()
1616
MIDI Note Velocity
1717
]]
1818
finaleplugin.AdditionalDescriptions = [[
19-
Change the MIDI duration of notes by layer
20-
Change the MIDI velocity of notes by layer
19+
Change the MIDI duration of notes on a chosen layer
20+
Change the MIDI velocity of notes on a chosen layer
2121
]]
2222
finaleplugin.AdditionalPrefixes = [[
2323
action = 0
2424
action = 2
2525
]]
2626
finaleplugin.ScriptGroupName = "MIDI Note Values"
27-
finaleplugin.ScriptGroupDescription = "Change the MIDI velocity and duration values of notes by layer"
27+
finaleplugin.ScriptGroupDescription = "Change the MIDI velocity and duration of notes on a chosen layer"
2828
finaleplugin.Notes = [[
29-
Change the playback MIDI Velocity and Duration (Start/Stop times)
29+
Change the playback __MIDI Velocity__ and __Duration__ (Start/Stop times)
3030
of every note in the currently selected music on one or all layers.
31-
Choose the "MIDI Note Values" menu item to change both at once or set them independently with the
32-
"MIDI Note Duration" and "MIDI Note Velocity" menu items.
31+
Choose the _MIDI Note Values_ menu item to change both at once or set them
32+
independently with _MIDI Note Duration_ and _MIDI Note Velocity_.
3333
34-
If Human Playback is active, "Velocity" and "Start/Stop Time" must be set to "HP Incorporate Data" at
35-
[Finale -> Settings -> Human Playback -> MIDI Data] to affect playback.
36-
Otherwise set "Key Velocities" and "Note Durations" to "Play Recorded"
37-
under "Playback/Record Options" in the "Playback Controls" window.
34+
To affect playback when _Human Playback_ is active you must set
35+
_Velocity_ and _Start/Stop Time_ to __HP Incorporate Data__ at
36+
_Settings_ → _Human Playback_ → _MIDI Data_.
37+
Otherwise set _Key Velocities_ and _Note Durations_ to __Play Recorded__
38+
under _Playback/Record Options_ in the _Playback Controls_ window.
3839
Note that some playback samples don't respond to velocity settings.
3940
40-
Holding down the SHIFT or ALT (option) keys when invoking a menu item
41-
will make the changes using your most recent values without showing any
42-
confirmation dialog window (or any other visual confirmation!)
41+
Hold down [Shift] when opening the script to
42+
repeat your last choices without a confirmation dialog.
43+
Layer number is "clamped" to a single character so to change
44+
layer just type a new number - delete key not needed.
4345
]]
44-
return "MIDI Note Values...", "MIDI Note Values", "Change the MIDI velocity and duration values of notes by layer"
46+
return "MIDI Note Values...",
47+
"MIDI Note Values",
48+
"Change the MIDI velocity and duration of notes on a chosen layer"
4549
end
4650

4751
action = action or 1 -- 0 = Duration only / 1 = Both / 2 = Velocity only
52+
53+
local configuration = require("library.configuration")
54+
local mixin = require("library.mixin")
55+
local layer = require("library.layer")
56+
local utils = require("library.utils")
57+
local library = require("library.general_library")
58+
local script_name = library.calc_script_name()
59+
local focus_document = false -- set to true if utils.show_notes_dialog is used
60+
4861
local config = {
4962
layer = 0,
5063
start_offset = 0,
@@ -53,88 +66,97 @@ local config = {
5366
window_pos_x = false, -- saved dialog window position
5467
window_pos_y = false,
5568
}
69+
local options = { -- key; text description
70+
start_offset = "Start time (EDU):",
71+
stop_offset = "Stop time (EDU):",
72+
velocity = "Key Velocity (0-127):",
73+
layer = "Layer 1-" .. layer.max_layers() .. " (0 = all):"
74+
}
5675

57-
local configuration = require("library.configuration")
58-
local mixin = require("library.mixin")
59-
local layer = require("library.layer")
60-
local script_name = "midi_note_values"
61-
62-
function user_error()
63-
local max = layer.max_layers()
64-
local msg = ""
65-
if config.layer < 0 or config.layer > max then
66-
msg = "Layer number must be an integer between zero and " .. max .. " (not " .. config.layer .. ").\n\n"
67-
end
68-
if (action <= 1) -- duration" or both
69-
and (math.abs(config.start_offset) > 9999 or math.abs(config.stop_offset) > 9999) then
70-
msg = msg .. "Offset levels must be reasonable, say -9999 to 9999 (not " ..
71-
config.start_offset .. " to " .. config.stop_offset .. "). \n\n"
72-
end
73-
if (action >= 1) -- "velocity" or both
74-
and (config.velocity < 0 or config.velocity > 127) then
75-
msg = msg .. "Velocity must be an integer between 0 and 127 (not " .. config.velocity .. "). "
76-
end
77-
if msg ~= "" then
78-
finenv.UI():AlertInfo(msg, "User Error")
79-
return true
80-
end
81-
return false
82-
end
83-
84-
function dialog_set_position(dialog)
76+
local function dialog_set_position(dialog)
8577
if config.window_pos_x and config.window_pos_y then
8678
dialog:StorePosition()
8779
dialog:SetRestorePositionOnlyData(config.window_pos_x, config.window_pos_y)
8880
dialog:RestorePosition()
8981
end
9082
end
9183

92-
function dialog_save_position(dialog)
84+
local function dialog_save_position(dialog)
9385
dialog:StorePosition()
9486
config.window_pos_x = dialog.StoredX
9587
config.window_pos_y = dialog.StoredY
88+
configuration.save_user_settings(script_name, config)
9689
end
9790

98-
function user_choices(basekey)
91+
local function user_choices()
9992
local offset = finenv.UI():IsOnMac() and 3 or 0 -- extra y-offset for Mac EDIT box
10093
local y, y_step = offset, 25
10194
local edit_x, e_wide = 120, 45
95+
local saved = {}
96+
local dialog = mixin.FCXCustomLuaWindow():SetTitle(finaleplugin.ScriptGroupName)
97+
-- local functions
98+
local function show_info()
99+
utils.show_notes_dialog(dialog, "About " .. finaleplugin.ScriptGroupName, 400, 247)
100+
focus_document = true -- return focus to document
101+
end
102+
local function key_check(ctl, name) -- inhibit alphabetic keys and some negation
103+
local val = ctl:GetText()
104+
if val:find("[^-0-9]")
105+
or (name == "layer" and val:find("[^0-" .. layer.max_layers() .. "]"))
106+
or (name == "velocity" and val:find("-"))
107+
then
108+
if val:find("[?q]") then show_info() end
109+
ctl:SetText(saved[name]):SetKeyboardFocus()
110+
elseif val ~= "" then
111+
if name == "layer" then
112+
val = val:sub(-1) -- one character only
113+
elseif name == "velocity" then
114+
if tonumber(val) > 127 then val = "127" end
115+
else -- EDU offsets
116+
local num_chars = (val:sub(1,1) == "-") and 5 or 4
117+
val = val:sub(1, num_chars) -- 4/5 characters max
118+
end
119+
ctl:SetText(val)
120+
saved[name] = val
121+
end
122+
end
123+
local function create_value(name)
124+
saved[name] = config[name] -- restore config values
125+
dialog:CreateStatic(0, y):SetText(options[name]):SetWidth(edit_x)
126+
dialog:CreateEdit(edit_x, y - offset, name):SetText(saved[name])
127+
:SetWidth((name == "layer") and 20 or e_wide)
128+
:AddHandleCommand(function(self) key_check(self, name) end)
129+
y = y + y_step
130+
end
102131

103-
local dialog = mixin.FCXCustomLuaWindow():SetTitle(plugindef())
104132
if (action <= 1) then -- "duration" or both
105-
dialog:CreateStatic(0, y):SetText("Start time (EDU):"):SetWidth(edit_x)
106-
dialog:CreateEdit(edit_x, y - offset, "start"):SetInteger(config.start_offset or 0):SetWidth(e_wide)
107-
y = y + y_step
108-
dialog:CreateStatic(0, y):SetText("Stop time (EDU):"):SetWidth(edit_x)
109-
dialog:CreateEdit(edit_x, y - offset, "stop"):SetInteger(config.stop_offset or 0):SetWidth(e_wide)
110-
y = y + y_step
133+
create_value("start_offset")
134+
create_value("stop_offset")
111135
end
112136
if (action >= 1) then -- "velocity" or both
113-
dialog:CreateStatic(0, y):SetText("Key Velocity (0-127):"):SetWidth(edit_x)
114-
dialog:CreateEdit(edit_x, y - offset, "velocity"):SetInteger(config.velocity or basekey):SetWidth(e_wide)
115-
y = y + y_step
137+
create_value("velocity")
116138
end
117-
dialog:CreateStatic(0, y):SetText("Layer 1-4 (0 = all):"):SetWidth(edit_x)
118-
dialog:CreateEdit(edit_x, y - offset, "layer"):SetInteger(config.layer or 0):SetWidth(e_wide)
119-
139+
create_value("layer") -- always
140+
dialog:CreateButton(edit_x + 26, y - y_step):SetText("?"):SetWidth(20)
141+
:AddHandleCommand(function() show_info() end)
120142
dialog:CreateOkButton()
121143
dialog:CreateCancelButton()
122144
dialog:RegisterHandleOkButtonPressed(function(self)
123-
config.layer = self:GetControl("layer"):GetInteger()
124-
if (action <= 1) then
125-
config.start_offset = self:GetControl("start"):GetInteger()
126-
config.stop_offset = self:GetControl("stop"):GetInteger()
127-
end
128-
if (action >= 1) then
129-
config.velocity = self:GetControl("velocity"):GetInteger()
145+
for k, _ in pairs(options) do
146+
local ctl = self:GetControl(k)
147+
if ctl then config[k] = ctl:GetInteger() end
130148
end
131-
dialog_save_position(self)
132149
end)
133150
dialog_set_position(dialog)
134-
return dialog
151+
dialog:RegisterCloseWindow(function() dialog_save_position(dialog) end)
152+
return (dialog:ExecuteModal() == finale.EXECMODAL_OK)
135153
end
136154

137-
function change_values(basekey)
155+
function change_values()
156+
local prefs = finale.FCPlaybackPrefs()
157+
prefs:Load(1)
158+
local basekey = prefs:GetBaseKeyVelocity()
159+
138160
for entry in eachentrysaved(finenv.Region(), config.layer) do
139161
if entry:IsNote() then
140162
local perf_mod = finale.FCPerformanceMod()
@@ -160,25 +182,13 @@ end
160182

161183
function midi_note_values()
162184
configuration.get_user_settings(script_name, config, true)
163-
local basekey = 64
164-
if action >= 1 then -- velocity
165-
local prefs = finale.FCPlaybackPrefs()
166-
prefs:Load(1)
167-
basekey = prefs:GetBaseKeyVelocity()
168-
end
185+
local qim = finenv.QueryInvokedModifierKeys
186+
local mod_down = qim and (qim(finale.CMDMODKEY_ALT) or qim(finale.CMDMODKEY_SHIFT))
169187

170-
local mod_down = finenv.QueryInvokedModifierKeys and
171-
(finenv.QueryInvokedModifierKeys(finale.CMDMODKEY_ALT)
172-
or finenv.QueryInvokedModifierKeys(finale.CMDMODKEY_SHIFT)
173-
)
174-
if not mod_down then -- modifiers inhibit confirmation dialog
175-
local dialog = user_choices()
176-
if (dialog:ExecuteModal(nil) ~= finale.EXECMODAL_OK) or user_error() then
177-
return -- user cancelled or made a mistake
178-
end
179-
configuration.save_user_settings(script_name, config)
188+
if mod_down or user_choices() then
189+
change_values()
180190
end
181-
change_values(basekey)
191+
if focus_document then finenv.UI():ActivateDocumentWindow() end
182192
end
183193

184194
midi_note_values()

0 commit comments

Comments
 (0)