[JW Lua] Create Harp Gliss script

Jari Williamsson jari.williamsson at mailbox.swipnet.se
Tue Oct 8 15:26:47 CEST 2013


Hello All!

I made a script for creating harp glissandi and a Wiki tutorial on how 
to set up the script:
http://www.jwmusic.nu/jwplugins/wiki/doku.php?id=jwlua:harpglisssample

The script is also attached to this message.


Best regards,

Jari Williamsson
-------------- next part --------------
-- CHANGE THESE 2 VALUES IF YOU WANT OTHER VALUES

StemLength = 84   -- Stem Length of the first note in EVPUs

SmallNoteResize = 70   -- Resize % of small notes



function plugindef()

   -- This function and the 'finaleplugin' namespace

   -- are both reserved for the plug-in definition.

   finaleplugin.RequireSelection = true

   finaleplugin.MinFinaleVersion = "2012"

   finaleplugin.Author = "Jari Williamsson"

   finaleplugin.Version = "0.01"

   finaleplugin.Notes = [[

This script will only process 7-tuplets that appears on staves that has been defined as "Harp" in the Score Manager.

]]

   finaleplugin.CategoryTags = "Idiomatic, Note, Pluckedstrings, Region, Tuplet, Woodwinds"

   return "Harp gliss (from 7-tuplet)", "Harp gliss", "Transforms 7-tuplets to harp gliss notation."

end





-- Sets the beam width to 0 and resizes the stem for the first note (by moving

-- the primary beam)

-- This is a sub-function to ChangePrimaryBeam()

function ChangeBeamInfo(primarybeam, entry)

    local currentlength = entry:CalcStemLength()

    primarybeam.Thickness = 0  

    if entry:CalcStemUp() then

        primarybeam.LeftVerticalOffset = primarybeam.LeftVerticalOffset + StemLength - currentlength

    else

        primarybeam.LeftVerticalOffset = primarybeam.LeftVerticalOffset - StemLength + currentlength

    end

end



-- Changes a primary beam for and entry

function ChangePrimaryBeam(entry)    

    local primarybeams = finale.FCPrimaryBeamMods(entry)

    primarybeams:LoadAll()

    if primarybeams.Count > 0 then

        -- Modify the existing beam modification record to hide the beam

        local primarybeam = primarybeams:GetItemAt(0)        

        ChangeBeamInfo(primarybeam, entry)        

        primarybeam:Save()

    else

        -- Create a beam modification record and hide the beam

        local primarybeam = finale.FCBeamMod(false)

        primarybeam:SetNoteEntry(entry)

        ChangeBeamInfo(primarybeam, entry)         

        primarybeam:SaveNew()

    end

end



-- Assures that the entries that spans the entries are

-- considered "valid" for a harp gliss. Rests and too few

-- notes in the tuplet are things that aren't ok.

-- This is a sub-function to GetMatchingTuplet()

function VerifyEntries(entry, tuplet)

    local entrystaffspec = finale.FCCurrentStaffSpec()

    entrystaffspec:LoadForEntry(entry)

    if entrystaffspec.InstrumentUUID ~= finale.FFUUID_HARP then return false end

    local symbolicduration = 0

    local firstentry = entry

    for i = 0, 6 do

        if entry == nil then return false end

        if entry:IsRest() then return false end

        if entry.Duration >= finale.QUARTER_NOTE then return false end        

        if entry.Staff ~= firstentry.Staff then return false end

        if entry.Layer ~= firstentry.Layer then return false end

        if entry:CalcDots() > 0 then return false end

        symbolicduration = symbolicduration + entry.Duration

        entry = entry:Next()

    end

    return (symbolicduration == tuplet:CalcFullSymbolicDuration())

end



-- If a "valid" harp tuplet is found for an entry, this method returns it.

function GetMatchingTuplet(entry)    

    local tuplets = entry:CreateTuplets()

    for t in each(tuplets) do

        if t.SymbolicNumber == 7 and VerifyEntries(entry, t) then return t end

    end

    return nil

end



-- Hides a tuplet (both by visibility and appearance)

function HideTuplet(t)    

    t.ShapeStyle = finale.TUPLETSHAPE_NONE

    t.NumberStyle = finale.TUPLETNUMBER_NONE

    t.Visible = false

    t:Save()

end



-- Hide stems for the small notes in the gliss. If the "full" note has a long

-- enough duration to not have a stem, the first entry also gets a hidden stem.

function HideStems(entry, tuplet)

    local hidefirstentry = (tuplet:CalcFullReferenceDuration() >= finale.WHOLE_NOTE)

    for i = 0, 6 do        

        if i > 0 or hidefirstentry then

            local stem = finale.FCCustomStemMod()        

            stem:SetNoteEntry(entry)

            stem:UseUpStemData(entry:CalcStemUp())

            if stem:LoadFirst() then

                stem.ShapeID = 0    

                stem:Save()

            else

                stem.ShapeID = 0

                stem:SaveNew()

            end            

        end

        entry = entry:Next()

    end

end



-- Change the notehead shapes and notehead sizes

function SetNoteheads(entry, tuplet)

    for i = 0, 6 do        

        for chordnote in each(entry) do

            local notehead = finale.FCNoteheadMod()                        

            if i == 0 then

                local fullrefdur = tuplet:CalcFullReferenceDuration()

                if fullrefdur >= finale.WHOLE_NOTE then

                    notehead.CustomChar = 119   -- Whole note character

                elseif fullrefdur >= finale.HALF_NOTE then

                    notehead.CustomChar = 250   -- Half note character

                end

            else

                notehead.Resize = SmallNoteResize

            end                    

            notehead:SaveAt(chordnote)                

        end

        entry = entry:Next()

    end

end



-- If the tuplet spans a duration that is dotted, modify the

-- rhythm at the beginning of the tuplet

function ChangeDottedFirstEntry(entry, tuplet)

    local refdur = tuplet:CalcFullReferenceDuration()

    local tupletdots = finale.FCNoteEntry.CalcDotsForDuration(refdur)

    local entrydots = entry:CalcDots()    

    if tupletdots == 0 then return end

    if tupletdots > 3 then return end  -- Don't support too complicated gliss rhythm values

    if entrydots > 0 then return end

    -- Create dotted rhythm

    local nextentry = entry:Next()

    local nextduration = nextentry.Duration / 2    

    for i = 1, tupletdots do

        entry.Duration = entry.Duration + nextduration

        nextentry.Duration = nextentry.Duration - nextduration

        nextduration = nextduration / 2

    end

end



-- *** THE SCRIPT EXECUTION STARTS HERE ***



-- Make sure the harp tuplets are beamed

for entry in eachentrysaved(finenv.Region()) do

    local harptuplet = GetMatchingTuplet(entry)

    if harptuplet then

        harp_tuplets_exist = true

        for  i = 1, 6 do

            entry = entry:Next()

            entry.BeamBeat = false

        end

    end

end



if harp_tuplets_exist == nil then return end



-- Since the entries might change direction when they are beamed,

-- tell Finale to update the entry metric data info

finale.FCNoteEntry.MarkEntryMetricsForUpdate()



-- Change the harp tuplets

for entry in eachentrysaved(finenv.Region()) do

    local harptuplet = GetMatchingTuplet(entry)

    if harptuplet then

        ChangeDottedFirstEntry(entry, harptuplet)

        ChangePrimaryBeam(entry)

        HideTuplet(harptuplet)

        HideStems(entry, harptuplet)

        SetNoteheads(entry, harptuplet)

    end        

end


More information about the JWLua mailing list