-----DEBUG CONTROL-------------------------------------------------------------- debug_output = false -- true/false --display debug messages in the console -----DISPLAY CONSOLE MESSAGE---------------------------------------------------- -- Display a message in the console for debugging, message can be a number variable -- or a string but not mixed. No line feed character is added. function Msg(value) --returns nothing if debug_output then --check if flag is set true (at the start of this script) reaper.ShowConsoleMsg(tostring(value).."\n") end end -- NoIndex: true --[[ Lokasenna_GUI example - Getting user input before running an action; i.e. replacing GetUserInputs --]] -------------------------------- --REATRAK LOCAL GUI LIBRARY start -------------------------------- --[[ local info = debug.getinfo(1,'S'); script_path = info.source:match[[^@?(.*[\/])[^\/]-$]] --Msg("script_path "..script_path) --[[ local lib_path = script_path --reaper.GetExtState("Lokasenna_GUI", "lib_path_v2") --]] --if not lib_path or lib_path == "" then --reaper.MB("Couldn't load the ReaTrak Lokasenna_GUI library. Please check Scripts/ReaTrak/ReaTrak_Classes/", "Whoops!", 0) --return --end --[[ loadfile(script_path .. "ReaTrak_Core.lua")() GUI.req(script_path .. "ReaTrak_Classes/Class - Label.lua")() GUI.req(script_path .. "ReaTrak_Classes/Class - Knob.lua")() GUI.req(script_path .. "ReaTrak_Classes/Class - Tabs.lua")() GUI.req(script_path .. "ReaTrak_Classes/Class - Slider.lua")() GUI.req(script_path .. "ReaTrak_Classes/Class - Button.lua")() GUI.req(script_path .. "ReaTrak_Classes/Class - Menubox.lua")() GUI.req(script_path .. "ReaTrak_Classes/Class - Textbox.lua")() GUI.req(script_path .. "ReaTrak_Classes/Class - Frame.lua")() GUI.req(script_path .. "ReaTrak_Classes/Class - Options.lua")() GUI.req(script_path .. "ReaTrak_Classes/Class - Window.lua")() --]] -------------------------------- --REATRAK LOCAL GUI LIBRARY end -------------------------------- -------------------------------- --LOKASENNA GUI LIBRARY start -------------------------------- -- NoIndex: true --[[ Lokasenna_GUI example - Getting user input before running an action; i.e. replacing GetUserInputs ]]-- -- The Core library must be loaded prior to anything else reaper.MB("Using Lokasenna_GUI library", "Notice", 0) local lib_path = reaper.GetExtState("Lokasenna_GUI", "lib_path_v2") if not lib_path or lib_path == "" then reaper.MB("Couldn't load the Lokasenna_GUI library. Please run 'Script: Set Lokasenna_GUI v2 library path.lua' in your Action List.", "Whoops!", 0) return end loadfile(lib_path .. "Core.lua")() GUI.req("Classes/Class - Slider.lua")() GUI.req("Classes/Class - Button.lua")() GUI.req("Classes/Class - Menubox.lua")() GUI.req("Classes/Class - Options.lua")() GUI.req("Classes/Class - Label.lua")() GUI.req("Classes/Class - Frame.lua")() GUI.req("Classes/Class - Textbox.lua")() -------------------------------- --LOKASENNA GUI LIBRARY end -------------------------------- -- If any of the requested libraries weren't found, abort the script nicely. if missing_lib then return 0 end -- Button Colors = {r, g, b, transparency} GUI.colors["count_in"] = {255, 124, 192, 255} GUI.colors["intro_post_fill"] = {119, 17, 174, 255} GUI.colors["intro"] = {159, 22, 232, 255} GUI.colors["intro_fill"] = {183, 128, 237, 255} GUI.colors["verse_post_fill"] = {17, 39, 174, 255} GUI.colors["verse"] = {55, 118, 235, 255} GUI.colors["verse_fill"] = {113, 190, 241, 255} GUI.colors["verse_ending"] = {151, 208, 245, 255} GUI.colors["bridge_post_fill"] = {206, 105, 20, 255} GUI.colors["bridge"] = {234, 133, 48, 255} GUI.colors["bridge_fill"] = {239, 164, 100, 255} GUI.colors["pre_chorus_post_fill"] = {206, 179, 20, 255} GUI.colors["pre_chorus"] = {234, 208, 48, 255} GUI.colors["pre_chorus_fill"] = {244, 231, 151, 255} GUI.colors["chorus_post_fill"] = {11, 116, 39, 255} GUI.colors["chorus"] = {17, 174, 59, 255} GUI.colors["chorus_fill"] = {80, 237, 123, 255} GUI.colors["chorus_ending"] = {158, 254, 182, 255} GUI.colors["play_anywhere"] = {228, 26, 39, 250} GUI.colors["drum_riff"] = {115, 23, 17, 255} GUI.colors["hold"] = {191, 191, 191, 255} GUI.colors["shot"] = {127, 127, 127, 255} GUI.colors["rest"] = {0, 0, 0, 255} GUI.colors["stop"] = {151, 0, 75, 255} ------------------------------------ -------- Functions ---------------- ------------------------------------ ----------------------------------------- function Check_Scale(pitch, pat) local note = pitch % 12 +1 --Msg(note) local q_note for i = 1, 12 do if pat[i] then q_note = i end if pat[i] and i == note then return pitch end if not pat[i] and i == note then return pitch - (i-q_note) end end --Msg(q_note) return pitch end ----------------------------------------- function tablelength(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end ----------------------------------------- -- Check if table has specific value local function has_value (tab, val) for index, value in ipairs(tab) do if value == val then return true end end return false end --We can use the above in an if conditional to get our result. --[[ if has_value(arr, 'b') then Msg('Yep') else Msg('Nope') end --]] ----------------------------------------- function string:split(sep) local sep, fields = sep or ":", {} local pattern = string.format("([^%s]+)", sep) self:gsub(pattern, function(c) fields[#fields+1] = c end) return fields end ----------------------------------------- --Is item in table function has_key(table, key) return table[key]~=nil end ----------------------------------------- --Find nearest valu in table --[[8 x = 15 table = {190, 1, 12, 18} --]] function NearestValue(table, number) local smallestSoFar, smallestIndex for i, y in ipairs(table) do if not smallestSoFar or (math.abs(number-y) < smallestSoFar) then smallestSoFar = math.abs(number-y) smallestIndex = i end end return smallestIndex, table[smallestIndex] end function tableHasKey(table,key) return table[key] ~= nil end function table_invert(t) local u = { } for k, v in pairs(t) do u[v] = k end return u end function position_in_table(table,key_name) local index={} for k,v in pairs(table) do index[v]=k end return index[key_name] end function tally(t) local freq = {} for _, v in ipairs(t) do freq[v] = (freq[v] or 0) + 1 end return freq end function dump(t) for k, v in pairs(t) do Msg(k ..",".. v) end end function nt2_write(path, data, sep) sep = sep or ',' local file = assert(io.open(path, "w")) file:write('Image ID' .. "," .. 'Caption') file:write('\n') for k, v in pairs(data) do file:write(v["image_id"] .. "," .. v["caption"]) file:write('\n') end file:close() end function print_r (t, fd) fd = fd or io.stdout local function print(str) str = str or "" fd:write(str.."\n") end end function btn_click_set_source() source_item = reaper.GetSelectedMediaItem( 0, 0 ) source_take = reaper.GetActiveTake( source_item ) retval, source_name = reaper.GetSetMediaItemTakeInfo_String( source_take, "P_NAME", "", 0 ) GUI.elms.set_source_item_label:ondelete() GUI.New("set_source_item_label", "Label", 1, 10, 42, source_name , true, 1, "chorus_ending") GUI.elms.set_source_item_label.font = {"Arial", 17, "bi"} GUI.elms.set_source_item_label:init() --GUI.elms.snap_selected_item_label:ondelete() --GUI.New("snap_selected_item_label", "Label", 1, 10, 102, "No Item Snapped" , true, 1, "play_anywhere") --GUI.elms.snap_selected_item_label.font = {"Arial", 17, "bi"} --GUI.elms.snap_selected_item_label:init() end function count_source_notes() --reaper.PreventUIRefresh(1) reaper.Main_OnCommand(40289, 0) -- Item: Unselect all items reaper.SetMediaItemSelected( source_item, 1 ) --set media item source_item selected source_item_take = reaper.GetActiveTake(source_item) reaper.MIDI_SelectAll(source_item_take, 0) --reaper.Main_OnCommand(40153, 0) --Item: Open in built-in MIDI editor (set default behavior in preferences) --reaper.Main_OnCommand(40847, 0) -- Item: Open item inline editors --ME = reaper.MIDIEditor_GetActive() --------------------------------------------- --Select all notes starting in time selection --------------------------------------------- sel_start, sel_end = reaper.GetSet_LoopTimeRange( false, false, 0, 0, false ) Msg("sel_start " .. sel_start .. " sel_end " .. sel_end) --reaper.MIDI_GetProjTimeFromPPQPos( source_take, ppqpos ) sel_start_ppq = reaper.MIDI_GetPPQPosFromProjTime( source_item_take, sel_start ) sel_end_ppq = reaper.MIDI_GetPPQPosFromProjTime( source_item_take, sel_end ) _, notecnt = reaper.MIDI_CountEvts( source_item_take ) --Msg("notecnt "..notecnt) selection_ppqend = 0 for i = 0, notecnt -1 do _, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote( source_item_take, i ) Msg("pitch ".. pitch) if startppqpos >= sel_start_ppq and startppqpos <= sel_end_ppq -2 then Msg("Set Seleceted") reaper.MIDI_SetNote( source_item_take, i , true, muted, startppqpos, endppqpos, chan, pitch, vel, false ) --set note selected if endppqpos > selection_ppqend then selection_ppqend = endppqpos end end end --------------------------------------------- --Set time selection to selected notes --------------------------------------------- new_sel_end = reaper.MIDI_GetProjTimeFromPPQPos( source_item_take, selection_ppqend ) sel_start, sel_end = reaper.GetSet_LoopTimeRange( true, false, sel_start, new_sel_end, false ) --------------------------- --Count selected midi notes --------------------------- --reaper.MIDIEditor_OnCommand( ME, 40877 ) --Edit: Select all notes starting in time selection --reaper.MIDIEditor_OnCommand( ME, 40752 ) --Edit: Set time selection to selected notes --sel_start, sel_end = reaper.GetSet_LoopTimeRange( false, false, 0, 0, false ) reaper.SetEditCurPos2( 0, sel_end, 0, 0 ) --if not ME then return end --midi_source_take = reaper.MIDIEditor_GetTake(ME) --if not take or not reaper.TakeIsMIDI(take) then return end _, notecnt = reaper.MIDI_CountEvts( source_item_take ) --Msg("notecnt "..notecnt) --if not notecnt then -- next_region() -- end count = 0 sel_count = 0 low_pitch = 0 hi_pitch =127 last_pitch = 0 first_note_index = 0 Msg("Source Notes ============================") sel_notes = {} for i = 0, notecnt -1 do _, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote( source_item_take, i ) if selected then --Msg("Found Selected note ".. pitch .." @ ".. i) table.insert(sel_notes, "Pitch="..pitch .. " Idx="..i) if count == 0 then first_note_index = i -- first selected note idx --Msg("count "..count) --Msg("first note ".. pitch .." @ ".. i) last_pitch = pitch hi_pitch = pitch end if pitch <= last_pitch then --low_pitch = pitch last_pitch = pitch end if pitch >= hi_pitch then hi_pitch = pitch last_pitch = pitch end last_count = count count = count +1 last_note = i end --Msg("sel_notes[sel_note_index] "..sel_notes[1].Idx) end table.sort(sel_notes, function(a,b) return a < b end) --Msg("SAVE TABLE ON") --table.save( sel_notes , "C:\\temp\\table-sel_notes.txt" ) pattern = "Pitch=(%d+) Idx=(%d+)" -- "(%d+),(%d+)" --local pitch_i, i_pitch = sel_notes[i]:match(pattern) --Pitch=52 Idx=55 --pitch_i = tonumber(pitch_i) --i_pitch = tonumber(i_pitch) --Msg("pitch_i "..pitch_i) --Msg("i_pitch "..i_pitch) --Msg("first_note_index "..first_note_index) --Msg("sel_notes[1] "..sel_notes[1]) note_str = tostring(sel_notes[1]) --Msg("note_str "..note_str) low_pitch, low_idx = note_str:match(pattern) --Msg("low_pitch "..low_pitch) selected_pitch_order = {} order = 0 --for i = first_note_index , (first_note_index + count) do --for i = first_note_index, first_note_index + count do -- -1 do for i = 0, notecnt do _, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote( source_item_take, i ) if selected then order = order +1 --Msg("Found Selected note 2 ".. pitch .." @ ".. i) selected_pitch_order[order] = { sort_pitch = pitch, sort_idx = i} --table.insert(sel_notes, "Pitch="..pitch .. " Idx="..i) end end table.sort(selected_pitch_order, function(a,b) return a.sort_pitch < b.sort_pitch end) --Msg("SAVE TABLE ON") --table.save( sel_notes , "C:\\temp\\table-sel_pitch_order.txt" ) --Print Notes for i = 1, count do --Msg("note ".. selected_pitch_order[i].sort_pitch .. " idx " ..selected_pitch_order[i].sort_idx) end --Msg("count "..count) --Msg("low_pitch "..low_pitch) --Msg("hi_pitch "..hi_pitch) --Msg("first_note_index "..first_note_index) --Msg("last_pitch "..last_pitch) chord_notes_table = {} -- Insert slash notes into table octave = 0 for i = 1, count do insert_note = selected_pitch_order[i].sort_pitch if insert_note > -1 and insert_note < 128 then table.insert(chord_notes_table, tonumber(insert_note)) end --Msg("Chord Table ".. insert_note) insert_note = selected_pitch_order[i].sort_pitch +12 if insert_note > -1 and insert_note < 128 then table.insert(chord_notes_table, tonumber(insert_note)) end end --[[ chord_root_table = {} insert_note = selected_pitch_order[1].sort_pitch if insert_note > -1 and insert_note < 128 then table.insert(chord_root_table, tonumber(insert_note)) end Msg("Root Table ".. insert_note) insert_note = selected_pitch_order[1].sort_pitch +12 if insert_note > -1 and insert_note < 128 then table.insert(chord_root_table, tonumber(insert_note)) end --]] --reaper.MB( "count_source_notes", "title", 0 ) --table.sort(chord_root_table) table.sort(chord_notes_table) chord_notes_table_count = tablelength(chord_notes_table) --Msg("Chord Table index 1 " .. chord_notes_table[1]) --Msg("Chord Table index 2 " .. chord_notes_table[2]) --reaper.MIDIEditor_OnCommand( ME, 2 ) --File: Close window reaper.MIDI_SelectAll(source_item_take, 0) --reaper.PreventUIRefresh(-1) end function btn_click_set_target() target_item = reaper.GetSelectedMediaItem( 0, 0 ) target_take = reaper.GetActiveTake( target_item ) retval, target_name = reaper.GetSetMediaItemTakeInfo_String( target_take, "P_NAME", "", 0 ) GUI.elms.set_target_item_label:ondelete() GUI.New("set_target_item_label", "Label", 1, 10, 102, target_name, true, 1, "chorus_ending") GUI.elms.set_target_item_label.font = {"Arial", 17, "bi"} GUI.elms.set_target_item_label:init() end function set_target_notes() --reaper.PreventUIRefresh(1) reaper.Main_OnCommand(40289, 0) -- Item: Unselect all items reaper.SetMediaItemSelected( target_item, 1 ) --set media item target_item selected target_item_take = reaper.GetActiveTake(target_item) reaper.MIDI_SelectAll(target_item_take, 0) target_item_pos = reaper.GetMediaItemInfo_Value( source_item, "D_POSITION" ) target_item_len = reaper.GetMediaItemInfo_Value( source_item, "D_LENGTH" ) target_item_end = target_item_pos + target_item_len --reaper.Main_OnCommand(40153, 0) --Item: Open in built-in MIDI editor (set default behavior in preferences) --ME = reaper.MIDIEditor_GetActive() --if not ME then return end --midi_target_take = reaper.MIDIEditor_GetTake(ME) --if not take or not reaper.TakeIsMIDI(take) then return end --reaper.MIDIEditor_OnCommand( ME, 40877 ) --Edit: Select all notes starting in time selection --------------------------------------------- --Select all notes starting in time selection --------------------------------------------- sel_start, sel_end = reaper.GetSet_LoopTimeRange( false, false, 0, 0, false ) Msg("sel_start " .. sel_start .. " sel_end " .. sel_end) --reaper.MIDI_GetProjTimeFromPPQPos( source_take, ppqpos ) sel_start_ppq = reaper.MIDI_GetPPQPosFromProjTime( source_item_take, sel_start ) sel_end_ppq = reaper.MIDI_GetPPQPosFromProjTime( source_item_take, sel_end ) _, notecnt = reaper.MIDI_CountEvts( target_item_take ) --Msg("notecnt "..notecnt) selection_ppqend = 0 for i = 0, notecnt -1 do _, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote( target_item_take, i ) Msg("pitch ".. pitch) if startppqpos >= sel_start_ppq and startppqpos <= sel_end_ppq -2 then Msg("Set Seleceted") reaper.MIDI_SetNote( target_item_take, i , true, muted, startppqpos, endppqpos, chan, pitch, vel, false ) --set note selected if endppqpos > selection_ppqend then selection_ppqend = endppqpos end end end _, notecnt = reaper.MIDI_CountEvts( target_item_take ) --Msg("notecnt "..notecnt) --if not notecnt then -- next_region() -- end count = 0 sel_count = 0 low_pitch = 0 hi_pitch =127 last_pitch = 0 first_note_index = 0 Msg("Target Notes=================================") sel_notes = {} for i = 0, notecnt -1 do _, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote( target_item_take, i ) if selected then --Msg("Found Selected note ".. pitch .." @ ".. i) table.insert(sel_notes, "Pitch="..pitch .. " Idx="..i) if count == 0 then first_note_index = i -- first selected note idx --Msg("count "..count) --Msg("first note ".. pitch .." @ ".. i) last_pitch = pitch hi_pitch = pitch end if pitch <= last_pitch then --low_pitch = pitch last_pitch = pitch end if pitch >= hi_pitch then hi_pitch = pitch last_pitch = pitch end last_count = count count = count +1 last_note = i end --Msg("sel_notes[sel_note_index] "..sel_notes[1].Idx) end table.sort(sel_notes, function(a,b) return a < b end) --Msg("SAVE TABLE ON") --table.save( sel_notes , "C:\\temp\\table-sel_notes.txt" ) pattern = "Pitch=(%d+) Idx=(%d+)" -- "(%d+),(%d+)" --local pitch_i, i_pitch = sel_notes[i]:match(pattern) --Pitch=52 Idx=55 --pitch_i = tonumber(pitch_i) --i_pitch = tonumber(i_pitch) --Msg("pitch_i "..pitch_i) --Msg("i_pitch "..i_pitch) --Msg("first_note_index "..first_note_index) --Msg("sel_notes[1] "..sel_notes[1]) note_str = tostring(sel_notes[1]) --Msg("note_str "..note_str) low_pitch, low_idx = note_str:match(pattern) --Msg("low_pitch "..low_pitch) selected_pitch_order = {} order = 0 --for i = first_note_index , (first_note_index + count) do --for i = first_note_index, first_note_index + count do -- -1 do for i = 0, notecnt do _, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote( target_item_take, i ) if selected then order = order +1 --Msg("Found Selected note 2 ".. pitch .." @ ".. i) selected_pitch_order[order] = { sort_pitch = pitch, sort_idx = i} --table.insert(sel_notes, "Pitch="..pitch .. " Idx="..i) end end table.sort(selected_pitch_order, function(a,b) return a.sort_pitch < b.sort_pitch end) --Msg("SAVE TABLE ON") --table.save( sel_notes , "C:\\temp\\table-sel_pitch_order.txt" ) --Print Notes for i = 1, count do --Msg("note ".. selected_pitch_order[i].sort_pitch .. " idx " ..selected_pitch_order[i].sort_idx) end --Msg("count "..count) --Msg("low_pitch "..low_pitch) --Msg("hi_pitch "..hi_pitch) --Msg("first_note_index "..first_note_index) --Msg("last_pitch "..last_pitch) --Msg("sel_notes[1].Pitch "..sel_notes[1].Idx) previous_note = -1 previous_chord_notes_table_index = 0 root_note_number = 0 root_table_index = 0 chord_notes_table_index = 0 current_chord_notes_table_index = 0 --for i = first_note_index, (first_note_index + count)-1 do --Msg("count through notes and set new pitch") --for i = first_note_index, (first_note_index + count)-1 do for i = 1, count do -- -1 do --Msg("#note ".. selected_pitch_order[i].sort_pitch .. " #idx " ..selected_pitch_order[i].sort_idx) pitch_i = selected_pitch_order[i].sort_pitch i_pitch = selected_pitch_order[i].sort_idx low_pitch = selected_pitch_order[1].sort_pitch if pitch_i == low_pitch then --root_table_index, new_pitch = NearestValue(chord_root_table, pitch_i) --Msg("chord root number = "..root_table_index) --Msg("root number new pitch "..new_pitch) --Msg("note idx ".. i_pitch) new_pitch = chord_notes_table[1] root_note = chord_notes_table[1] --new_pitch = chord_root_table[root_table_index] if not new_pitch then break end --Msg("new_pitch "..new_pitch) root_note_number = new_pitch current_chord_notes_table_index = 1 --chord_notes_table_index = position_in_table(chord_notes_table,root_note_number) --Msg("chord_notes_table_index "..chord_notes_table_index) --current_chord_notes_table_index = chord_notes_table_index --Msg("current_chord_notes_table_index ".. current_chord_notes_table_index) --root_note_number_index = chord_notes_table[root_note_number] --Msg("root_note_number_index "..root_note_number_index) --root_pitch_index = table_index end if pitch_i == previous_note then --Msg("previous_note "..previous_note) --Msg("pitch_i "..pitch_i) --Msg("previous_note "..previous_note .." pitch_i ".. pitch_i) new_pitch = chord_notes_table[previous_chord_notes_table_index] --if not new_pitch then break end current_chord_notes_table_index = position_in_table(chord_notes_table, new_pitch) --Msg("previous_note "..previous_note) --Msg("= previous new_pitch "..new_pitch) end if pitch_i > low_pitch and pitch_i > previous_note then --Msg("pitch > low_pitch "..pitch_i) if pitch_i > previous_note and pitch_i > root_note_number +23 then new_pitch = position_in_table(chord_notes_table, current_chord_notes_table_index +1) --if not new_pitch then break end current_chord_notes_table_index = position_in_table(chord_notes_table, new_pitch) end if pitch_i > root_note_number +23 and previous_note < root_note_number +23 then --Msg("Next Octave Pitch "..pitch_i) root_table_index, new_pitch = NearestValue(chord_root_table, pitch_i) new_pitch = chord_root_table[root_table_index] --if not new_pitch then break end root_note_number = new_pitch --new_pitch = chord_notes_table[chord_notes_table_index] current_chord_notes_table_index = position_in_table(chord_notes_table, new_pitch) --Msg("previous_note "..previous_note) --Msg("new_pitch "..new_pitch) else if pitch_i > previous_note and pitch_i < root_note_number +23 then --Msg("pitch_i ".. pitch_i) chord_notes_table_index = position_in_table(chord_notes_table, current_chord_notes_table_index +1) --Msg("root_note_number "..root_note_number) --Msg("chord_notes_table_index "..chord_notes_table_index) --new_pitch = chord_notes_table_index new_pitch = chord_notes_table[previous_chord_notes_table_index +1] if not new_pitch then break end current_chord_notes_table_index = position_in_table(chord_notes_table, new_pitch) --Msg("previous_note "..previous_note) --Msg("else new_pitch < root_note_number +23 "..new_pitch) --chords_table() end if pitch_i > previous_note and pitch_i > root_note_number +23 then new_pitch = chord_notes_table[previous_chord_notes_table_index +1] if not new_pitch then break end current_chord_notes_table_index = position_in_table(chord_notes_table, new_pitch) --current_chord_notes_table_index = previous_chord_notes_table_index --Msg("previous_note "..previous_note) --Msg("else new_pitch > root_note_number +23 "..new_pitch) --chords_table() end end end previous_note = pitch_i --new_pitch previous_chord_notes_table_index = current_chord_notes_table_index current_pitch = new_pitch --Msg("current_chord_notes_table_index "..tostring(current_chord_notes_table_index)) --sel_note_idx = sel_notes[i].Idx _, selected, muted, startppqpos, endppqpos, chan, current_pitch, vel = reaper.MIDI_GetNote( target_item_take, i_pitch ) --Msg("Current Note Position "..current_pitch) --Msg("NOTE SHIFT ON") --extra_notes = GUI.Val("note_mode") extra_notes = GUI.elms.notes_mode.optarray[ GUI.Val("notes_mode") ] --Msg("extra_notes "..extra_notes) Msg("root_note "..root_note) Msg("root_note+11 "..root_note +11) Msg("new_pitch "..new_pitch) if new_pitch > root_note +11 then if extra_notes == "Mute" then mute = 1 Msg("mute note") end if extra_notes == "Next Octave" then mute = 0 end end reaper.MIDI_SetNote( target_item_take, i_pitch , true, mute, startppqpos, endppqpos, chan, new_pitch, vel, true ) --reaper.MIDI_SetNote( take, i-1, true, muted, startppqpos, endppqpos, chan, new_pitch, vel, true ) _, selected, muted, startppqpos, endppqpos, chan, current_pitch, vel = reaper.MIDI_GetNote( target_item_take, i_pitch ) --Msg("Changed Note Position "..current_pitch) mute = 0 end --reaper.MIDIEditor_OnCommand( ME, 2 ) --File: Close window reaper.MIDI_SelectAll(target_item_take, 0) reaper.MIDI_Sort( target_item_take ) --reaper.PreventUIRefresh(-1) end ----------------------------------------- function btn_click_snap_target_item() reaper.PreventUIRefresh(1) if not target_item then reaper.MB( "Select Source & Target Items", "Not Selected", 0 ) goto finish end if not source_item then reaper.MB( "Select Source & Target Items", "Not Selected", 0 ) goto finish end reaper.Main_OnCommand(40289, 0) -- Item: Unselect all items --reaper.SetMediaItemSelected( target_item, 1 ) --set media item target_item selected source_item_pos = reaper.GetMediaItemInfo_Value( source_item, "D_POSITION" ) source_item_len = reaper.GetMediaItemInfo_Value( source_item, "D_LENGTH" ) source_item_end = source_item_pos + source_item_len reaper.SetEditCurPos2( 0, source_item_pos, 0, 0 ) -- Initial start set ::next_chord:: reaper.Main_OnCommand(40625, 0) --Time selection: Set start point reaper.Main_OnCommand(41044, 0) --Move edit cursor forward one beat reaper.Main_OnCommand(40626, 0) --Time selection: Set end point --[[ reaper.Main_OnCommand(40153, 0) --Item: Open in built-in MIDI editor (set default behavior in preferences) --MIDI Editor ME1 = reaper.MIDIEditor_GetActive() sorce_take = reaper.MIDIEditor_GetTake(ME1) --reaper.MIDIEditor_OnCommand( ME1, 2 ) --File: Close window reaper.MIDIEditor_OnCommand( ME1, 40877 ) --Edit: Select all notes starting in time selection --Edit: Select all notes in measure reaper.MIDIEditor_OnCommand( ME1, 40752 ) --Edit: Set time selection to selected notes --then to get the next chord reaper.MIDIEditor_OnCommand( ME1, 40881 ) --Move cursor to end of time selection --Navigate: Move edit cursor to start of next measure --]] count_source_notes() set_target_notes() --reaper.MB( "msg", "title", 0 ) cur_pos = reaper.GetCursorPosition() if cur_pos < source_item_end and cur_pos < target_item_end then goto next_chord end GUI.elms.set_target_item_label:ondelete() GUI.New("set_target_item_label", "Label", 1, 10, 102, "Snapped: " ..target_name, true, 1, "pre_chorus") GUI.elms.set_target_item_label.font = {"Arial", 17, "bi"} GUI.elms.set_target_item_label:init() --GUI.elms.snap_selected_item_label:ondelete() --GUI.New("snap_selected_item_label", "Label", 1, 10, 102, "Snapped: " .. target_name, true, 1, "pre_chorus") --GUI.elms.snap_selected_item_label.font = {"Arial", 17, "bi"} --GUI.elms.snap_selected_item_label:init() --reaper.PreventUIRefresh(-1) reaper.Main_OnCommand(40635, 0) --Time selection: Remove time selection ::finish:: end ------------------------------------ -------- Window settings ----------- ------------------------------------ GUI.name = "Snap Notes to Chord Reference" GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, 470, 240 GUI.anchor, GUI.corner = "mouse", "C" ------------------------------------ -------- GUI Elements -------------- ------------------------------------ --[[ Button z, x, y, w, h, caption, func[, ...] Checklist z, x, y, w, h, caption, opts[, dir, pad] Menubox z, x, y, w, h, caption, opts, pad, noarrow] Slider z, x, y, w, caption, min, max, defaults[, inc, dir] ]]-- --GUI.New("chk_opts", "Checklist", 1, 192, 32, 192, 96, "Options", "Only in time selection,Only on selected track,Glue items when finished", "v", 4) --GUI.New("sldr_thresh", "Slider", 1, 32, 96, 128, "Threshold", -60, 0, 48, nil, "h") GUI.New("btn_set_source", "Button", 1, 10, 12, 220, 24, "Set Selected Item as Chord Reference", btn_click_set_source) GUI.New("set_source_item_label", "Label", 1, 10, 42, "Refrence Item not set" , true, 1, "play_anywhere") GUI.elms.set_source_item_label.font = {"Arial", 17, "bi"} GUI.New("btn_set_target", "Button", 1, 10, 72, 220, 24, "Selected Target Item", btn_click_set_target) GUI.New("set_target_item_label", "Label", 1, 10, 102, "Target Item not set" , true, 1, "play_anywhere") GUI.elms.set_target_item_label.font = {"Arial", 17, "bi"} GUI.New("btn_snap_selected_item", "Button", 1, 10, 142, 220, 24, "Snap", btn_click_snap_target_item) GUI.New("notes_mode", "Menubox", 1, 130, 172, 112, 20, "Extra Chord Notes:", "Next Octave,Mute") extra_notes = GUI.elms.notes_mode.optarray[ GUI.Val("notes_mode") ] GUI.Init() GUI.Main() ----------------------------------------- reaper.Undo_BeginBlock() reaper.PreventUIRefresh(1) --count_regions() --main() --reaper.MIDIEditor_OnCommand( hwnd, 2 ) --File: Close window --reaper.Undo_EndBlock('Snap notes to chord reference', 0) --reaper.PreventUIRefresh(-1) reaper.defer(function () end)