Created
January 27, 2022 08:39
-
-
Save ftsf/5bde507d79298d8cd7097623a59712b4 to your computer and use it in GitHub Desktop.
Synthesizer V - Transpose In Key Script
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
function getClientInfo() | |
return { | |
name = "Transpose In Key", | |
author = "impbox", | |
versionNumber = 1, | |
minEditorVersion = 0 | |
} | |
end | |
function getTranslations(langCode) | |
-- please help add translations <3 | |
return {} | |
end | |
-- Wrapper function to know the flow of code | |
function main() | |
--[[ | |
1st check user inputs | |
2nd start a core routine | |
3rd end plugin | |
]] | |
if validateBeforeStarting() then | |
local formResult = SV:showCustomDialog(makeForm()) | |
if (formResult.status) then | |
coreRoutine(formResult) | |
end | |
end | |
SV:finish() | |
end | |
-- Validate user request | |
function validateBeforeStarting() | |
-- if selected notes is empty, show message box and finish | |
if #SV:getMainEditor():getSelection():getSelectedNotes() < 1 then | |
SV:showMessageBox(SV:T("Selected Notes is Empty"), SV:T("You have to select at least one note.")) | |
return false | |
end | |
return true | |
end | |
-- create custom dialog form | |
function makeForm() | |
local form = { | |
title = SV:T("Transpose in Key"), | |
message = SV:T("Choose key and transpose interval."), | |
buttons = "OkCancel", | |
widgets = { | |
{ | |
name = "key", | |
type = "ComboBox", | |
label = SV:T("Key"), | |
choices = {"C","C#/Db","D","D#/Eb","E","F","F#/Gb","G","G#/Ab","A","A#/Bb","B"}, | |
default = 0 | |
}, | |
{ | |
name = "minor", | |
type = "CheckBox", | |
text = "Minor", | |
default = false | |
}, | |
{ | |
name = "interval", | |
type = "ComboBox", | |
label = SV:T("Interval"), | |
choices = {"+2nd", "+3rd", "+4th", "+5th", "+6th", "+7th", "+8ve", "-2nd", "-3rd", "-4th", "-5th", "-6th", "-7th", "-8ve"}, | |
default = 3 | |
}, | |
} | |
} | |
return form | |
end | |
intervalToSemitones = { | |
{2,1}, | |
{4,3}, | |
{5,4,6}, | |
{7,6,8}, | |
{9,8,10}, | |
{11,10}, | |
{12}, | |
{-2,-1}, | |
{-4,-3}, | |
{-5,-4,-6}, | |
{-7,-6,-8}, | |
{-9,-8,-10}, | |
{-12}, | |
} | |
keyNames = {"C","C#/Db","D","D#/Eb","E","F","F#/Gb","G","G#/Ab","A","A#/Bb","B"} | |
majorScale = {0,2,4,5,7,9,11,12} | |
minorScale = {0,2,3,5,7,8,10,12} | |
function isInKey(key, isMinor, note) | |
local noteWithoutOctave = note % 12 | |
local keyRootNote = key - 1 | |
local scale = nil | |
if isMinor then scale = minorScale else scale = majorScale end | |
for i = 1, #majorScale, 1 do | |
if (keyRootNote + scale[i]) % 12 == noteWithoutOctave then | |
return true | |
end | |
end | |
return false | |
end | |
function coreRoutine(formResult) | |
local notes = SV:getMainEditor():getSelection():getSelectedNotes() | |
--SV:showMessageBox("Transposing...", "notes: " .. #notes) | |
local key = formResult.answers.key + 1 | |
local minor = formResult.answers.minor | |
local interval = formResult.answers.interval + 1 | |
--SV:showMessageBox("Transposing...", "key: " .. key .. " minor: " .. minor .. " interval: " .. interval) | |
--SV:showMessageBox("Transposing...", "Key: " .. key .. " " .. keyNames[key] .. " minor: " .. minor .. " interval: " .. interval) | |
local intervalsToCheck = intervalToSemitones[interval] | |
--SV:showMessageBox("Transposing...", "Key: " .. keyNames[key] .. " interval: " .. interval .. " to check: " .. #intervalsToCheck) | |
for i = 1, #notes, 1 do | |
-- go through each note and increment it and snap it to the scale | |
local note = notes[i]:getPitch() - 60 | |
--SV:showMessageBox("Transposing...", "note: " .. note) | |
for j = 1, #intervalsToCheck, 1 do | |
local tryNote = note + intervalsToCheck[j] | |
--SV:showMessageBox("Transposing...", "note: " .. note .. " + " .. intervalsToCheck[j] .. " -> " .. tryNote) | |
if isInKey(key, minor, tryNote) then | |
--SV:showMessageBox("Transposing...", "note: " .. note .. " -> " .. tryNote .. " is in key!") | |
notes[i]:setPitch(tryNote + 60) | |
break | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment