Created
March 16, 2024 14:10
-
-
Save Flicksie/bf5a5beba456634654670e29169bc6fe to your computer and use it in GitHub Desktop.
Get highest / lowest not FL Piano Roll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import flpianoroll as flp | |
import math | |
PPQ = flp.score.PPQ | |
BEAT = PPQ * 4 | |
STEP = PPQ | |
SCAN_UNITS_STR = ['Tick', 'Half Beat', 'Odd Beat', 'Half Bar', 'Odd Bar'] | |
SCAN_UNITS = [1, STEP * 2, PPQ, PPQ * 2, BEAT] | |
if flp.score.noteCount == 0: | |
flp.Utils.ShowMessage("There are no notes!") | |
else: | |
def createDialog(): | |
"""Create a dialog to select note criteria.""" | |
Form = flp.ScriptDialog("Select Highest or Lowest Note", "") | |
Form.AddInputCombo("Select note", "Highest, Lowest, Middle", 0) | |
Form.AddInputCheckbox("Ignore singles", True) | |
Form.AddInputCombo("Scan at each", [unit_str for unit_str, unit in zip(SCAN_UNITS_STR, SCAN_UNITS) if unit < flp.score.length], 0) | |
return Form | |
def apply(dialog): | |
"""Apply the selected note criteria.""" | |
notes_starts = [flp.score.getNote(i).time for i in range(flp.score.noteCount)] | |
notes_ends = [note_start + flp.score.getNote(i).length - 1 if flp.score.getNote(i).length > 0 else note_start for i, note_start in enumerate(notes_starts)] | |
scan_unit = SCAN_UNITS[dialog.GetInputValue("Scan at each")] | |
num_of_scans = math.ceil((flp.score.length / scan_unit) / 2) | |
ignore_singles = dialog.GetInputValue("Ignore singles") | |
select_note = dialog.GetInputValue("Select note") | |
for scan_index in range(num_of_scans): | |
t = (((scan_index + 1) * 2) - 1) * scan_unit if scan_unit > 0 else scan_index # Calculate current time | |
notes_in_scan = [i for i, (start, end) in enumerate(zip(notes_starts, notes_ends)) if start <= t <= end] | |
if len(notes_in_scan) < 2 and ignore_singles: | |
continue | |
notes_numbers = [flp.score.getNote(i).number for i in notes_in_scan] | |
if notes_numbers: | |
max_note_index = notes_in_scan[notes_numbers.index(max(notes_numbers))] | |
min_note_index = notes_in_scan[notes_numbers.index(min(notes_numbers))] | |
if select_note == 0: # Highest | |
flp.score.getNote(max_note_index).selected = True | |
elif select_note == 1: # Lowest | |
flp.score.getNote(min_note_index).selected = True | |
else: # Middle (doesn't work all the time) | |
flp.score.getNote(max_note_index).selected = False | |
flp.score.getNote(min_note_index).selected = False | |
if max_note_index == min_note_index and not ignore_singles: | |
flp.score.getNote(min_note_index).selected = True | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment