Skip to content

Instantly share code, notes, and snippets.

@Flicksie
Created March 16, 2024 14:10
Show Gist options
  • Save Flicksie/bf5a5beba456634654670e29169bc6fe to your computer and use it in GitHub Desktop.
Save Flicksie/bf5a5beba456634654670e29169bc6fe to your computer and use it in GitHub Desktop.
Get highest / lowest not FL Piano Roll
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