User Tools

Site Tools


jwlua:harpglisssample

This is an old revision of the document!


Using JW Lua - Create Harp Glissando

If you have never used JW Lua to run scripts before, this is a good page to start. At the bottom of the page is a full script that will automatically create a harp gliss from a 7-tuplet that you might want to test (the script works on Finale 2012 and later versions).

This wiki page is based on beta version 0.07, but it should hopefully work with any later version as well.

Step 1 - Download and Install JW Lua

The beta versions of JW Lua are available for download at this page: http://finaletips.nu/index.php?option=com_phocadownload&view=category&id=28:beta-version&Itemid=2

Install the plug-in as any other third party Finale plug-in. The Windows version contains a DLL file as well, which must be put in the same folder as the plug-in .fxt file.

Step 2 - Start JW Lua

Once the JW Lua plug-in has been installed and Finale has been restarted, select JW Lua… in Finale's Plug-ins menu.

Step 3 - Create a script group

Step 4 - Add the script to the group

Step 5 - Refresh the plug-in list

Step 6 - Run

The Harp Glissando script

harpgliss.lua
-- 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
        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
jwlua/harpglisssample.1381232828.txt.gz · Last modified: 2013/10/08 11:47 by jariw