Skip to content

Commit bf1f316

Browse files
authored
Merge pull request #746 from cv-on-hub/cv_string_harmonics
Create string_harmonics.lua
2 parents df357eb + 23670ff commit bf1f316

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

src/string_harmonics.lua

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
function plugindef()
2+
finaleplugin.RequireSelection = true
3+
finaleplugin.Author = "Carl Vine"
4+
finaleplugin.AuthorURL = "https://carlvine.com/lua/"
5+
finaleplugin.Copyright = "https://creativecommons.org/licenses/by/4.0/"
6+
finaleplugin.Version = "0.63"
7+
finaleplugin.Date = "2024/07/21"
8+
finaleplugin.Notes = [[
9+
This script converts the __upper__ note of allowable _string harmonic_
10+
dyads (two-note chords) into __diamond__ noteheads.
11+
The first twelve harmonics of the lower _root_ pitch are recognised.
12+
13+
Three other scripts currently in the
14+
[FinaleLua.com ](https://FinaleLua.com) repository
15+
("_String harmonics_ __X__ _sounding pitch_") take single-pitch
16+
_sounding_ notes and create an equivalent played _string harmonic_ by adding a
17+
__diamond-headed__ _harmonic_ note, and transposing the resulting dyad
18+
downwards by the interval of the harmonic.
19+
]]
20+
return "String Harmonics",
21+
"String Harmonics",
22+
"Identify suitable string harmonic dyads and change the top note to a diamond notehead"
23+
end
24+
25+
local notehead = require("library.notehead")
26+
27+
function string_harmonics()
28+
-- recognised intervals for string harmonics measured in semitone STEPS,
29+
-- mapped to the corresponding diatonic interval
30+
local allowed = {
31+
[3] = 2, [4] = 2, [5] = 3, [7] = 4,
32+
[9] = 5, [12] = 7, [16] = 9, [19] = 11,
33+
[24] = 14, [28] = 16, [31] = 18
34+
}
35+
for entry in eachentrysaved(finenv.Region()) do
36+
if entry:IsNote() and (entry.Count == 2) then -- only treat dyads
37+
local highest = entry:CalcHighestNote(nil)
38+
local lowest = entry:CalcLowestNote(nil)
39+
local midi_diff = highest:CalcMIDIKey() - lowest:CalcMIDIKey()
40+
local displacement_diff = highest.Displacement - lowest.Displacement
41+
if allowed[midi_diff] and allowed[midi_diff] == displacement_diff then
42+
finale.FCNoteheadMod():EraseAt(lowest)
43+
notehead.change_shape(highest, "diamond")
44+
end
45+
end
46+
end
47+
end
48+
49+
string_harmonics()

0 commit comments

Comments
 (0)