I am new to Dorico (using Dorico 5), and brand new to Dorico scripting. I asked Copilot to help me generate a script to select all of the notes on the “Tenor” staff, and change the key velocities to a target value. But it’s not working. Can anyone who is knowledgeable about Dorico scripting help me out? I’m sure the instrument name is correct.
local app=DoApp.DoApp()
local targetStaff = "Tenor"
local targetVelocity = 62
-- Use the 'app' global instead of 'Dorico'
-- We wrap the commands in a function to ensure clear execution
function run()
print("Executing velocity change for: " .. targetStaff )
-- 1. Ensure we are in Write Mode
app:doCommand([[Window.SwitchMode?WindowMode=kWriteMode]])
-- 2. Prime the selection to focus the score
-- This prevents the 'Go to Bar' dialog by ensuring the engine has a score context
app:doCommand([[Edit.SelectAtStartOfFlow]])
-- 3. Navigate to the staff using the Jump Bar logic
-- In Dorico 5, this is the most reliable way to jump to a specific instrument
app:doCommand([[Edit.GoTo?Instrument=]] .. targetStaff)
-- 4. Select all music on that staff
app:doCommand([[Edit.SelectAllOnStaff]])
-- 5. Filter for notes only
app:doCommand([[Filter.Notes]])
-- 6. Apply the velocity change
app:doCommand([[Property.Set?Velocity=]] .. targetVelocity)
-- 7. Cleanup
app:doCommand([[Edit.DeselectAll]])
print("Finished.")
end
-- Call the function at the end to ensure it runs when selected from the menu
run()
I don’t think those are all valid Dorico commands. For example, I think Filter.Notes should be Filter.NotesAndChords, and I don’t think Filter.SelectAllOnStaff exists.
Copilot is good at a number of coding tasks, but there’s so little source material to train on when it comes to Dorico scripting that I wouldn’t expect it to know much. You might be better off using the macro recording feature in Dorico to record yourself performing these steps, and then edit the resulting script to trim out things you don’t need and to refactor things like the staff name and target velocity variables.
Edit: Yeah, I just recorded myself performing these steps, and what I get doesn’t look much like what Copilot suggests. The selection seems to be done at a point on the screen rather than a staff location, and the select to end of staff and set property commands are completely different.
@Christian_R shows a minimal script that assumes you’re already in Write mode and just selects everything on the staff and changes the velocity.
Why are you interested in scripting this action? If it’s just to learn more about scripting, that’s one thing (and I think macro recording feature would be more helpful than Copilot), but if it’s for practical use, it seems to me that this is a really easy action to do by hand and doesn’t benefit from being scripted.
Thanks for your reply! Agreed about the Copilot limitations; I am just starting to get into using it at work, and wanted to see if it could help me here. It took a lot of tries to get to where we ended up, and it obviously isn’t correct still.
I did try macro recording, and ended up having the same experience as you. Since the resulting script was based on screen coordinates, it wasn’t reusable.
As for why I want to automate this: I am using Dorico to generate rehearsal tracks for a choir I am associated with. Since I enter the notes using a MIDI keyboard, I found that it retained the key velocities, so I couldn’t just change them using a dynamic marking. So my approach has been to manipulate the key velocities.
To emphasize a particular voice for generating the playback, I increase the velocities of the notes for that part. I also copy the notes to a different staff with an electric piano instrument, to get the slight percussive effect to indicate when each note begins. I also change the instrument of the voice I am emphasizing. So going from one voice to another involves multiple tedious steps and takes about a minute or longer. Which isn’t that long, but I thought I’d try to automate it. I used to do this work in Finale, and I could make the changes for each part in just a few seconds.
Let me know if you have any other ideas to help. Not just with scripting, but with better ways to control the playback dynamics other than working with key velocities. I would much rather just set a new dynamic marking in the first measure, but so far I haven’t been able to figure out how to do that.
Thanks! The “Select to end of system” worked, but the note velocities didn’t change. Note that I am going into Play mode to view and change my note velocities; I don’t know if that’s relevant.
Thanks for the suggestion. I tried that previously, and again just now at your suggestion, and it didn’t work either time. It’s still retaining my key velocities when I do playback.
Thanks for all the help! Still struggling mightily. I recorded a macro like you showed. What I got was different than what you sent the first time. Also, running it still didn’t change the note velocities. Here’s what I got. The last line seems wrong to me:
local app=DoApp.DoApp()
app:doCommand([[Edit.SelectAtEndOfFlow]])
app:doCommand([[EventEdit.EditExistingOrEnterStepTimeInput]])
app:doCommand([[NoteInput.Enter?Set=1]])
app:doCommand([[Play.PianoRollNoteVelocityChange?BlobID=222]])
You have shown me something useful, though. I had been using Play mode to change the velocities, which was cumbersome because “Select to End of Flow” wasn’t working there. But now I can see that I can do it in Write mode, which is more convenient. Thanks!
Can you (or anyone) point me to some “Getting started” help for Dorico scripting, and/or some examples? I didn’t see anything at all about scripting in the Dorico help, though maybe I didn’t look in the right place!
I could be wrong, but I don’t think there’s a command for that. But I imagine it’s much quicker to select the note yourself and run the script above, rather than needing to change the name of the staff in the script and then run it.