--[[ * ReaScript Name: Import markers and regions from tab-delimited CSV file * Description: See title. * Instructions: Select a track. Run. * Author: X-Raym * Author URI: http://www.extremraym.com * Repository: GitHub > X-Raym > EEL Scripts for Cockos REAPER * Repository URI: https://github.com/X-Raym/REAPER-EEL-Scripts * Links Forum Thread https:FMsg(" //forum.cockos.com/showthread.php?p=1670961 * Licence: GPL v3 * REAPER: 5.0 * Version: 1.0 --]] --[[ * Changelog: * v1.0 (2019-01-26) + Initial Release --]] -- USER CONFIG AREA ----------------------------------------------------------- -- Duplicate and Rename the script if you want to modify this. -- Else, a script update will erase your mods. -- Display a message in the console for debugging function Msg(value) if console then reaper.ShowConsoleMsg(tostring(value) .. "\n") end end function split_region_cursor() commandID4 = reaper.NamedCommandLookup("_RS3374194533e692527a47ca4ede0688a20fd691fd") reaper.Main_OnCommand(commandID4, 0) -- Script: ReaTrak split regions at tempo markers.lua --[[ reaper.Undo_BeginBlock() -- Begining of the undo block. Leave it at the top of your main function. tempo_markers_count = reaper.CountTempoTimeSigMarkers(0) for i = 0, tempo_markers_count - 1 do retval, timepos, measurepos, beatpos, bpm1, timesig_num, timesig_denom, lineartempo = reaper.GetTempoTimeSigMarker(0, i) reaper.SetEditCurPos(timepos, 0, 0) retval, num_markers, num_regionsOut = reaper.CountProjectMarkers(0) desired_region_id = num_regionsOut time = reaper.GetCursorPosition() markeridx, regionidx = reaper.GetLastMarkerAndCurRegion(0, time) retval, isrgn, pos, rgnend, name, markrgnindexnumber, color = reaper.EnumProjectMarkers3(0, regionidx) if time == pos then goto finish end if time < rgnend then reaper.SetProjectMarker3( 0, markrgnindexnumber, 1, pos, time, name, color ) reaper.AddProjectMarker2(0, 1, time, rgnend, name, desired_region_id, color) end ::finish:: end reaper.Undo_EndBlock("Split Regions at tempo markers", -1) -- End of the undo block. Leave it at the bottom of your main function. --]] end function get_tempo_cursor() current_cursor_pos2 = reaper.GetCursorPosition() timesig_num, timesig_denom, current_tempo = reaper.TimeMap_GetTimeSigAtTime(0, current_cursor_pos2) return end function get_tempo_markers() --Msg("function get_tempo_markers") bpm2 = bpm --region_length1 = region_length cur_pos = reaper.GetCursorPosition() tempo_markers_count = reaper.CountTempoTimeSigMarkers(0) for i = 0, tempo_markers_count - 1 do retval, timepos, measurepos, beatpos, bpm1, timesig_num, timesig_denom, lineartempo = reaper.GetTempoTimeSigMarker(0, i) --Msg("Main bpm1 ".. bpm1) --Msg("rgnpos,rgnend ".. rgnpos .. rgnend) --Msg("rgnpos ".. rgnpos) --Msg("timepos ".. timepos) --if beats_per_measure ~= timesig_num then break end --If tempo change occurs at region start --if timepos == cur_pos then bpm2 = bpm1 return end if timepos == rgnpos then --region_length1 = region_length --set_position = rgnpos bpm2 = bpm1 --return (bpm2) end --Msg("bpm2======================= ".. bpm2) return end --If tempo change occurs in region if timepos > rgnpos and timepos < rgnend then --region_length1 = (timepos - rgnpos) --set_position = timepos bpm2 = bpm1 --Msg("bpm1 ".. bpm1) return --break end end end console = true -- true/false: display debug messages in the console sep = "," -- default sep retval_inputs, retvals_csv = reaper.GetUserInputs( "Select Drums Extension & Offset", 2, ".wav .wma .m4a .aif .mp4 video,Offset (if any + - sec) eg. 5 -5", ".wma,0" ) realdrums_extension, user_offset = retvals_csv:match("([^,]+),([^,]+)") --user_offset = tonumber(user_offset) -- if not user_offset then user_offset = 0 end if not retval_inputs then goto finish2 end --Msg("File type "..realdrums_extension) tempo_markers_count = reaper.CountTempoTimeSigMarkers(0) if tempo_markers_count > 0 then --retval_split,input_yes = reaper.GetUserInputs("Region Split to Tempo Map", 1, "Split Regions @ Tempo changes ?", "yes") commandID1 = reaper.NamedCommandLookup("_RS3628f83c9f311bd67b97be26bb47f9d76c5cbaf9") reaper.Main_OnCommand(commandID1, 0) -- Script: ReaTrak Export regions as file.lua split_region_cursor() regions_saved = 1 --if not retval_split then goto end_split end --if input_yes == "yes" then --for i = 0, tempo_markers_count - 1 do --retval, timepos, measurepos, beatpos, bpm1, timesig_num, timesig_denom, lineartempo = reaper.GetTempoTimeSigMarker(0, i) --reaper.SetEditCurPos(timepos, 0, 0) --split_region_cursor() --end --end end ::end_split:: commandID3 = reaper.NamedCommandLookup("_SWSMARKERLIST8") reaper.Main_OnCommand(commandID3, 0) -- SWS: Renumber region IDs --Msg("Regions Renumbered") --(1)pattern,(2)type,(3)A verse B chorus,(4)weight,(5)mask,(6)duration,(7)bar --(1)shot,(2)0 shot 1 hold,(3)bar,(4)ticks,(5)duration ticks,weight,volume col_pos = 7 -- Position column index in the CSV col_pos_end = 4 -- Length column index in the CS col_len = 6 -- Length column index in the CSV col_name = 2 -- Name column index in the CSV col_color = 3 col_pattern = 1 col_ticks = 5 col_shot = 3 unit = 4 bpm, beat_per_measure = reaper.GetProjectTimeSignature2(0) --Msg("Project BPM ".. bpm) wavename = "" ------------------------------------------------------- END OF USER CONFIG AREA function ColorHexToInt(hex) hex = hex:gsub("#", "") local R = tonumber("0x"..hex:sub(1,2)) local G = tonumber("0x"..hex:sub(3,4)) local B = tonumber("0x"..hex:sub(5,6)) return reaper.ColorToNative(R, G, B) end -- Optimization local reaper = reaper -- CSV to Table -- http://lua-users.org/wiki/LuaCsv function ParseCSVLine (line,sep) local line = string.gsub(line, "{.*}", "") -- remove { } and text between them local line = string.gsub(line, ";.*", "") -- remove ; and text after it local line = string.gsub(line, "pattern,PreFill.*", "") -- remove pattern,PreFill line --if line == string.match(line,"wavename=.*") then wavename = line end --if line == string.match(line,"TimeSig=.*") then timesig = line end --if line == string.match(line,"Offset=.*") then offset = line end local res = {} local pos = 1 sep = sep or ',' while true do local c = string.sub(line,pos,pos) if (c == "") then break end if (c == '"') then -- quoted value (ignore separator within) local txt = "" repeat local startp,endp = string.find(line,'^%b""',pos) txt = txt..string.sub(line,startp+1,endp-1) pos = endp + 1 c = string.sub(line,pos,pos) if (c == '"') then txt = txt..'"' end -- check first char AFTER quoted string, if it is another -- quoted string without separator, then append it -- this is the way to "escape" the quote char in a quote. example: -- value1,"blub""blip""boing",value3 will result in blub"blip"boing for the middle until (c ~= '"') table.insert(res,txt) assert(c == sep or c == "") pos = pos + 3 else -- no quotes used, just look for the first separator local startp,endp = string.find(line,sep,pos) if (startp) then table.insert(res,string.sub(line,pos,startp-1)) pos = endp + 1 else -- no separator found -> use rest of string and terminate table.insert(res,string.sub(line,pos)) break end end end return res end -- UTILITIES ------------------------------------------------------------- -- Display a message in the console for debugging function Msg(value) if console then reaper.ShowConsoleMsg(tostring(value) .. "\n") end end function ReverseTable(t) local reversedTable = {} local itemCount = #t for k, v in ipairs(t) do reversedTable[itemCount + 1 - k] = v end return reversedTable end --------------------------------------------------------- END OF UTILITIES function read_lines(filepath) lines = {} local f = io.input(filepath) repeat s = f:read ("*l") -- read one line if s then -- if not end of file (EOF) table.insert(lines, ParseCSVLine (s,sep)) end until not s -- until end of file f:close() end function get_wavename() --function get_lines(filename) local lines = {} -- io.lines returns an iterator, so we need to manually unpack it into an array for line in io.lines(filetxt) do lines[#lines+1] = line --end if line == string.match(line,"wavename=.*") then wavename = line Msg("CSV2 wavename ".. wavename) end if line == string.match(line,"TimeSig=.*") then timesig = line Msg("CSV2 TimeSig ".. timesig) end if line == string.match(line,"Offset=.*") then offset = line Msg("CSV2 OffsetCap0 ".. offset) offsetCap = 0 end if line == string.match(line,"OFFSET=.*") then offset = line Msg("CSV2 OffsetCap1 ".. offset) offsetCap = 1 end return lines --end --local key, value = line:match("^([%w_]+)%s-=%s-(.+)$") end end function get_drum_values() vars = {} for line in io.lines(filetxt) do line = string.gsub(line, ";.*", "") -- remove ; and text after it var, val = line:match('^([^=]+)=(.*)') --if var then Msg("".. var .."=".. val) end if var == "wavename" then wavename1 = val end --Msg("wavename# ".. wavename) end if var == "TimeSig" then timesig = val end --Msg("TimeSig# ".. timesig) end if var == "Offset" then rd_offset = val end if var == "OFFSET" then rd_offset = val end if not line then end end --Msg("VARSOffset=".. vars.Offset) --Msg("wavename=".. vars.wavename) -- vars.wavename, vars.TimeSig, vars.Offset end -- Main function function drum_pattern() org_cur_pos = reaper.GetCursorPosition() get_drum_values() --Gets wavename from CSV to Table function ParseCSVLine adds the chosen file type extension --wavename1 = string.gsub(wavename, "wavename=", "") wavename2 = string.gsub(wavename1, ".wav", realdrums_extension) --Msg("Wavename2 ".. wavename2) --Gets BPM from wavename --Msg("Filename to get BPM from ".. wavename2) bb_bpm = string.match(wavename2, "%_+(%S+)%_") --Msg("BPM ".. bb_bpm) --Msg("RD Offset ticks ".. rd_offset) line_pos = string.find(bb_bpm, "0") if line_pos == 0 then bb_bpm1 = string.gsub(bb_bpm, "0","",1) end os_type = reaper.GetOS() -- "Mac OSX" -- "Win64" -- --slash = string.match(os_type, "Win") and "\\" or "/" if os_type ~= "Win32" and os_type ~= "Win64" then --Mac OS dir1 = string.gsub(filetxt, "/[^/]*$", "") dir = dir1 .."/" txt_filename1 = string.match(filetxt, "/[^/]*$") txt_filename = string.gsub(txt_filename1, "/", "") txt_filename_folder = string.gsub(wavename2, "_.*", "") -- remove _ and text after it blank_ext = string.gsub(txt_filename, ".txt", "") dir_back1 = string.gsub(dir1,"(.*)/.*$","%1") dir_back2 = string.gsub(dir_back1,"(.*)/.*$","%1") dir_back = dir_back1 .."/" txt_filename_folder2 = txt_filename_folder .."/" else --Win OS dir1 = string.gsub(filetxt, "\\[^\\]*$", "") dir = dir1 .."\\" txt_filename1 = string.match(filetxt, "\\[^\\]*$") txt_filename = string.gsub(txt_filename1, "\\", "") txt_filename_folder = string.gsub(wavename2, "_.*", "") -- remove _ and text after it blank_ext = string.gsub(txt_filename, ".txt", "") dir_back1 = string.gsub(dir1,"(.*)\\.*$","%1") dir_back2 = string.gsub(dir_back1,"(.*)\\.*$","%1") dir_back = dir_back1 .."\\" txt_filename_folder2 = txt_filename_folder .."\\" end match = 0 pass = 0 loop_number = 0 old_region_number2 = 0 previous_region = 0 pre_cursor_pos = 0 --dir and dir_back, if chosen file type is not found in current dir --it will look back a director --the "\\" "/" are worked out in os_type = reaper.GetOS() below open_file = dir .. wavename2 open_file_back = dir_back .. wavename2 open_file_back2 = dir_back .. txt_filename_folder2 .. wavename2 --Msg("open_file ".. open_file) --Msg("open_file_back ".. open_file_back) --Msg("open_file_back2 ".. open_file_back2) --open_file = ("\""..open_file.."\"") open_file = string.gsub(open_file, '^%s*(.-)%s*$', '%1') open_file_back = string.gsub(open_file_back, '^%s*(.-)%s*$', '%1') open_file_back2 = string.gsub(open_file_back2, '^%s*(.-)%s*$', '%1') --open_file_back = ("\""..open_file_back.."\"") --Msg("open_file_back ".. open_file_back) if reaper.file_exists(open_file) then file_source = open_file end if reaper.file_exists(open_file_back) then file_source = open_file_back end if reaper.file_exists(open_file_back2) then file_source = open_file_back2 end --Msg("open_file_back2 ".. open_file_back2) --Msg("Source file found in ".. file_source) --file_source = "/Applications/Band-in-a-Box/Drums/RockHardModernEv8^/RockHardModernEv8^_120_Style.m4a" --Msg("dir ".. dir) --Msg("txt_filename_folder ".. txt_filename_folder) --Msg("txt_filename_folder2 ".. txt_filename_folder2) --Msg("dir_back1 ".. dir_back1) --Msg("dir_back2 ".. dir_back2) --Msg("dir_back ".. dir_back) --Msg("wavename2 ".. wavename2) --Msg("Drum TimeSig ".. timesig) --Gets drums TimeSig and Offset from the text file in the CSV to Table if timesig == "3" and beat_per_measure == 4.0 then Info1 = [[ This Drum is "3" beats per measure]] reaper.MB(Info1, "Drum Beats Per Measure", 0) end if timesig == "4" and beat_per_measure == 3.0 then Info1 = [[ This Drum is "4" beats per measure]] reaper.MB(Info1, "Drum Beats Per Measure", 0) end --if offsetCap == 0 then rd_offset = string.gsub(offset, "Offset=", "") end --if offsetCap == 1 then rd_offset = string.gsub(offset, "OFFSET=", "") end --Msg("RD offset value " .. rd_offset) --copies the source file location into the system clipboard --reaper.CF_SetClipboard(file_source) --Msg("file_source ".. file_source) --to confirm it's in the clipboard Msg("buf".. buf) --buf = reaper.CF_GetClipboard(buf) --commandID1 = reaper.NamedCommandLookup("_XENAKIOS_INSERTMEDIAFROMCLIPBOARD") --reaper.Main_OnCommand(commandID1, 0) -- Xenakios/SWS: Insert media file from clipboard --Msg("file_source ".. file_source) reaper.InsertMedia( file_source, 0 ) reaper.Main_OnCommand(41173, 0) -- Item navigation: Move cursor to start of items Info = [[ The First time let the peaks draw then click Ok]] reaper.MB(Info, "Creating reapeak file", 0) imported_drums = reaper.GetSelectedMediaItem(0, 0) take = reaper.GetActiveTake( imported_drums ) --bpm = project tempo / drums tempo playrate = (bpm / bb_bpm) reaper.SetMediaItemTakeInfo_Value( take, "D_PLAYRATE", playrate ) reaper.Main_OnCommand(40699, 0) -- Edit: Cut items region_count , num_markersOut , num_regionsOut = reaper.CountProjectMarkers(0) region_number = 0 start_time, end_time = reaper.GetSet_LoopTimeRange2(0, false, false, 0, 0, false) _, first_region = reaper.GetLastMarkerAndCurRegion( 0, start_time ) _, last_region = reaper.GetLastMarkerAndCurRegion(0, end_time) if last_region == -1 then last_region = num_regionsOut end --- or reaper.GetLastMarkerAndCurRegion(0, end_time - 0.5) --the -0.5 is just a fudge to stop the next --Msg("last_region ".. last_region) --region_number = first_region if start_time == end_time then region_number = 0 --Msg("No Selection ") end if start_time ~= end_time then --Msg("Selection ") num_regionsOut = last_region region_number = first_region reaper.SetEditCurPos(start_time, 0, 0) end --Msg("start_time ".. start_time .." End time ".. end_time) --Msg("first_region ".. first_region) --Msg("region_number ".. region_number) --Msg("regionidx ".. regionidx) loop_stuck = 0 --region_number = first_region folder = filetxt:match[[^@?(.*[\/])[^\/]-$]] goto enum_regions ::enum_regions:: previous_region = region_number --Msg("region_number ".. region_number .." last_region ".. last_region) if start_time ~= end_time and region_number == last_region then goto finish end --if region_number == last_region -1 then goto finish end --reaper.SetEditCurPos(rgnpos, 0, 0) --Msg("enum_regions") --Msg("==================") --Msg("region_number ".. region_number) --Msg("last_region " .. last_region) --region_count , num_markersOut , num_regionsOut = reaper.CountProjectMarkers(0) retval, isrgn, rgnpos, rgnend, rgnname, markrgnindexnumber, rgncolor = reaper.EnumProjectMarkers3(0, region_number) tempo_markers_count = reaper.CountTempoTimeSigMarkers(0) --if tempo_markers_count == 0 then consecutive = 0 --======================================================================== -- JOIN CONSECUTIVE COLOR REGIONS count_markers_regions, count_markersOut, count_regionsOut = reaper.CountProjectMarkers(0) if region_number ~= count_regionsOut -1 and region_number == old_region_number2 then region_number = region_number +1 end --if region_number == old_region_number2 then region_number = region_number +1 end --Msg("region_number ".. region_number .. " old_region_number2 ".. old_region_number2) --Msg("===========================") --Msg("region_number ".. region_number .." count_regionsOut "..count_regionsOut) current_cursor_pos5 = reaper.GetCursorPosition() timesig_num, timesig_denom, current_tempo = reaper.TimeMap_GetTimeSigAtTime(0, current_cursor_pos5) count_markers_regions, count_markersOut, count_regionsOut = reaper.CountProjectMarkers(0) for i = region_number, count_regionsOut do iRetval, bIsrgnOut, iPosOut, iRgnendOut, sNameOut, iMarkrgnindexnumberOut, iColorOur = reaper.EnumProjectMarkers3(0,i) reaper.SetEditCurPos(iPosOut, 0, 0) current_cursor_pos3 = reaper.GetCursorPosition() timesig_num, timesig_denom, tempo_change = reaper.TimeMap_GetTimeSigAtTime(0, current_cursor_pos3) --Msg("current_tempo ".. current_tempo .." tempo_change "..tempo_change) if tempo_change ~= current_tempo then -- OR TEMPO CHANGE and TEMPO CHANGES OCCUR ON SPLIT REGIONS rgnend = iPosOut --consecutive = 1 break end if iColorOur == rgncolor then --i = i +1 region_number = region_number +1 end if region_number == last_region then rgnend = end_time break end if iColorOur ~= rgncolor then rgnend = iPosOut consecutive = 1 break end if i == count_regionsOut -1 then break end --end current_cursor_pos4 = reaper.GetCursorPosition() timesig_num, timesig_denom, current_tempo = reaper.TimeMap_GetTimeSigAtTime(0, current_cursor_pos4) --if consecutive == 0 then region_number = region_number -1 end --========================================================================== end old_region_number1 = region_number old_region_number2 = old_region_number1 region_number = region_number -1 --Msg("region_number ".. region_number) --Msg("rgnpos ".. rgnpos) --Msg("rgnname ".. rgnname) --Info = [[ Continue Ok]] --reaper.MB(Info, "PAUSE", 0) --when source file is pasted it will be at current region reaper.SetEditCurPos(rgnpos, 0, 0) goto start_match ::start_match:: --i = 2 if loop_stuck > 1200 then region_number = region_number +1 goto enum_regions end --goto finish end if region_number -1 == num_regionsOut then goto finish end for i, line in ipairs( lines ) do if line[col_pattern] == "Shot" or line[col_pattern] == "pattern" then --line[col_name] == "Shot" then -- if i > 1 then -- Name Variables local pos = line[col_pos] --local pos_end = tonumber(line[col_pos] +1) --tonumber(line[col_pos_end]) local len = line[col_len] local name = line[col_name] local color = 0 local dura_ticks = line[col_ticks] local ticks = line[col_pos_end] local shot_bar = line[col_shot] --Msg("Line Name ".. name) --(1)pattern,(2)type,(3)A verse B chorus,(4)weight,(5)mask,(6)duration,(7)bar --(1)shot,(2)0 shot 1 hold,(3)bar,(4)ticks,(5)duration ticks,weight,volume --col_pos = 7 -- Position column index in the CSV --col_pos_end = 4 -- Length column index in the CS --col_len = 6 -- Length column index in the CSV --col_name = 2 -- Name column index in the CSV --col_color = 3 --col_pattern = 1 --col_ticks = 5 if line[col_name] == "Count-in" then color = ColorHexToInt("#FF80C0")|0x1000000 --duration = 2 part = "Count-in" end if (line[col_color] == "A" or line[col_color] == "a") and line[col_name] == "PostFill" then color = ColorHexToInt("#1127AE")|0x1000000 --duration = 1 part = "Verse PostFill" end if (line[col_color] == "A" or line[col_color] == "a") and line[col_name] == "Normal" then color = ColorHexToInt("#3776EB")|0x1000000 --duration = 1 part = "Verse" end if (line[col_color] == "A" or line[col_color] == "a") and line[col_name] == "Fill" then color = ColorHexToInt("#71BEF1")|0x1000000 --duration = 1 part = "Verse Fill" end if line[col_color] == "Aending" and (line[col_name] == "ending" or line[col_name] == "Ending") then color = ColorHexToInt("#97D0FE")|0x1000000 --duration = 2 part = "Verse Ending" end if line[col_color] == "0" and (line[col_name] == "ending" or line[col_name] == "Ending") then -- any ending color color = ColorHexToInt("#42F4D1")|0x1000000 --duration = 2 part = "Any Ending" end if (line[col_color] == "B" or line[col_color] == "b") and line[col_name] == "PostFill" then color = ColorHexToInt("#0B7427")|0x1000000 --duration = 1 part = "Chorus PostFill" end if (line[col_color] == "B" or line[col_color] == "b") and line[col_name] == "Normal" then color = ColorHexToInt("#11AE3B")|0x1000000 --duration = 1 part = "Chorus" end if (line[col_color] == "B" or line[col_color] == "b") and line[col_name] == "Fill" then color = ColorHexToInt("#50ED7B")|0x1000000 --duration = 1 part = "Chorus Fill" end if line[col_color] == "Bending" and (line[col_name] == "ending" or line[col_name] == "Ending") then color = ColorHexToInt("#9EF5B6")|0x1000000 --duration = 2 part = "Chorus Ending" end --hold_color = 29343679 ---------------------BF BF BF R 127 G 127 B 127 #7F7F7F --shot_color = 25132927 ---------------------7F 7F 7F R 191 G 191 B 191 #BFBFBF -- Shots Holds if line[col_name] == "0" then color = ColorHexToInt("#7F7F7F")|0x1000000 -- Hold part = "Hold" end if line[col_name] == "1" then color = ColorHexToInt("#BFBFBF")|0x1000000 -- Shot part = "Shot" end --(1)pattern,(2)type,(3)A verse B chorus,(4)weight,(5)mask,(6)duration,(7)bar --(1)shot,(2)0 shot 1 hold,(3)bar,(4)ticks,(5)duration ticks,weight,volume --col_pos = 7 -- Position column index in the CSV --col_pos_end = 4 -- Length column index in the CS --col_len = 6 -- Length column index in the CSV --col_name = 2 -- Name column index in the CSV --col_color = 3 --col_pattern = 1 --col_ticks = 5 --retval, isrgn, rgnpos, rgnend, name, markrgnindexnumber, rgncolor = reaper.EnumProjectMarkers3(0, region_number) current_cursor_pos1 = reaper.GetCursorPosition() timesig_num, timesig_denom, bpm = reaper.TimeMap_GetTimeSigAtTime(0, current_cursor_pos1) --convert bar location and length from bars to time pos2 = ((((pos+1) * beat_per_measure)/ bb_bpm) * 60) len2 = ((((len) * beat_per_measure)/ bpm) * 60) bars_2 = ((((2) * beat_per_measure)/ bpm) * 60) region_length = (rgnend-rgnpos) --shot_bar1 = string.gsub(shot_bar, "A", "0") --shot_bar2 = string.gsub(shot_bar1, "B", "0") --if shot_bar == string.match(shot_bar, "%d") then --shot_bar2 = shot_bar --else shot_bar = "1" end duration2 = (dura_ticks / (bpm *2.5)) -- bpm *2 bb_bpm ?? --Msg("shot_bar_pos ".. shot_bar2) if line[col_name] == "0" then --Msg("Hold > ".. shot_bar) end if line[col_name] == "1" then --Msg("Shot > ".. shot_bar) end --This needs to match only digits in the column 3 col_shot to give shot bar pos if line[col_name] == "0" or line[col_name] == "1" then shot_bar1 = line[col_shot] shot_bar_pos = ((((shot_bar1+1) * beat_per_measure)/ bb_bpm) * 60) --shot_bar_pos = (shot_bar / (bb_bpm *2)) ticks_pos = (ticks / (bb_bpm *2)) bar_pos_start = shot_bar_pos + ticks_pos end --Msg("Shot Bar ".. shot_bar_pos) --Shot region reaper.AddProjectMarker2( 0, true, bar_pos_start, bar_pos_start + duration2, "" , -1, color ) --[[ --Skip Shot/Hold region (this is done in drum_shot() if rgncolor == ColorHexToInt("#BFBFBF")|0x1000000 then region_number = region_number +1 goto enum_regions end -- Hold if rgncolor == ColorHexToInt("#7F7F7F")|0x1000000 then region_number = region_number +1 goto enum_regions end -- Shot --if color == ColorHexToInt("#97D0FE")|0x1000000 and region_length > bars_2 then region_length = bars_2 goto skip_ending --if color == ColorHexToInt("#9EFEB6")|0x1000000 and region_length > bars_2 then region_length = bars_2 goto skip_ending --]] --Fit 2 bar Ending to larger bars if rgncolor == ColorHexToInt("#97D0FE")|0x1000000 and region_length > bars_2 then region_length = bars_2 end if rgncolor == ColorHexToInt("#9EF5B6")|0x1000000 and region_length > bars_2 then region_length = bars_2 end --Fit Vesre/Chorus Ending to Any Ending if color == ColorHexToInt("#42F4D1")|0x1000000 and rgncolor == ColorHexToInt("#97D0FE")|0x1000000 then rgncolor = ColorHexToInt("#42F4D1")|0x1000000 region_length = bars_2 end if color == ColorHexToInt("#42F4D1")|0x1000000 and rgncolor == ColorHexToInt("#9EF5B6")|0x1000000 then rgncolor = ColorHexToInt("#42F4D1")|0x1000000 region_length = bars_2 end -- ADD ANY ENDING then rgncolor = --Fit any lenght Shot/Hold to any legnth region if rgncolor == ColorHexToInt("#BFBFBF")|0x1000000 and color == ColorHexToInt("#BFBFBF")|0x1000000 and region_length > duration2 then region_length = duration2 shot_type = shot end -- shot if rgncolor == ColorHexToInt("#7F7F7F")|0x1000000 and color == ColorHexToInt("#7F7F7F")|0x1000000 and region_length > duration2 then region_length = duration2 shot_type = shot end --hols if rgncolor == ColorHexToInt("#BFBFBF")|0x1000000 and color == ColorHexToInt("#BFBFBF")|0x1000000 and duration2 > region_length then region_length = region_length shot_type = shot end --shot if rgncolor == ColorHexToInt("#7F7F7F")|0x1000000 and color == ColorHexToInt("#7F7F7F")|0x1000000 and duration2 > region_length then region_length = region_length shot_type = shot end --hold --[[ if rgncolor == ColorHexToInt("#BFBFBF")|0x1000000 and color == ColorHexToInt("#BFBFBF")|0x1000000 and duration2 > region_length then duration2 = region_length shot_type = shot end --shot if rgncolor == ColorHexToInt("#7F7F7F")|0x1000000 and color == ColorHexToInt("#7F7F7F")|0x1000000 and duration2 > region_length then duration2 = region_length shot_type = shot end --hold --]] --Msg("".. part .."bars ".. len .." Time ".. len2) --Msg("Reg ".. region_length) --Msg("Drum ".. color .." Reg Color ".. rgncolor) --var random_boolean = Math.random() < 0.7; --// 70% this will be true, 30% false+ --math.random(0, 1) == 1 and --math.random() pass = (math.random( 0, 4 ) ) --Msg("Pass ".. pass) --pass = pass + 1 if color == ColorHexToInt("#FF80C0")|0x1000000 and rgncolor == ColorHexToInt("#FF80C0")|0x1000000 then pass = 1 end -- Count-in if color == ColorHexToInt("#97D0FE")|0x1000000 and rgncolor == ColorHexToInt("#97D0FE")|0x1000000 then pass = 1 end -- Verse Ending if color == ColorHexToInt("#9EF5B6")|0x1000000 and rgncolor == ColorHexToInt("#9EF5B6")|0x1000000 then pass = 1 end -- Chorus Ending --[[ for 1=0, tempo_marker_count -1 do retval, timepos, measurepos, beatpos, bpm, timesig_num, timesig_denom, lineartempo = reaper.GetTempoTimeSigMarker(0, i) if measurepos == rgnpos if measurepos > rgnpos and measurepos <= regend --]] --Msg("region_length ".. region_length .." Drum Length ".. len2 .." part".. part) if pass == 1 and color == rgncolor and len2 >= (region_length -.011) then match = match +1 --Msg("Matched ") --Msg("Drum Color ".. color .." Region Color ".. rgncolor .. " ".. part .." pos ".. pos .." " .." \n ==============") --if color == ColorHexToInt("#97D0FE")|0x1000000 and item_length > bars_2 then item_length = bars_2 end --if color == ColorHexToInt("#9EFEB6")|0x1000000 and item_length > bars_2 then item_length = bars_2 end --get_tempo_markers() current_cursor_pos = reaper.GetCursorPosition() --if current_cursor_pos == pre_cursor_pos then region_number = region_number +1 goto enum_regions end -- pre_cursor_pos = current_cursor_pos timesig_num, timesig_denom, tempo = reaper.TimeMap_GetTimeSigAtTime(0, current_cursor_pos) --Msg("current_cursor_pos ".. current_cursor_pos) --if start_time ~= end_time and current_cursor_pos == end_time then goto finish end reaper.Main_OnCommand(40058, 0) -- Item: Paste items/tracks reaper.Main_OnCommand(41173, 0) -- Item navigation: Move cursor to start of items --Msg("Pasted @ ".. region_number .." > ".. current_cursor_pos) imported_drums = reaper.GetSelectedMediaItem(0, 0) take = reaper.GetActiveTake( imported_drums ) --(Reaper centi-beats 1 beat = 100) (Biab 1 beat = 120 ticks) --playrate2 = (tempo / bb_bpm) --reaper.SetMediaItemTakeInfo_Value( take, "D_PLAYRATE", playrate2 ) --Convert - to + and + to - offset --C = rd_offset --D = 0 - C --Msg("Offset= ".. rd_offset) rd_offset1 = 0 - rd_offset user_offset1 = 0 - user_offset --user_offset = (user_offset / (bb_bpm *2)) rd_offset2 =(rd_offset1 / 4000) --Msg("RD Offset Ticks ".. rd_offset) --Msg("RD Offset Time ".. rd_offset2) user_offset2 = (user_offset1 / 1000) --Msg("User Offset Time "..user_offset2) -- wam media_offset = .092 80bpm .12 .074 100bpm .12 -- mp4 media_offset = .050 80bpm .065 .039 100bpm .065 --pos2 = ((((pos+1) * beat_per_measure)/ bb_bpm) * 60) --the compressed media has a bit of delay at the start of the file --if realdrums_extension == ".wma" then media_offset = ((2 / bb_bpm) * 10) end -- .12 if realdrums_extension == ".wma" then media_offset = .047 end --((3.9 / bpm) * 5 ) end -- (lower more delay / bpm) * x lower more delay if realdrums_extension == ".m4a" then media_offset = 0 end --((.064 / bpm) * 45) end if realdrums_extension == ".mp4" then media_offset = .047 end -- = ((.064 / bpm) * 45) end if realdrums_extension == ".wav" then media_offset = 0 end if realdrums_extension == ".aif" then media_offset = 0 end --this is used in reaper.SetMediaItemTakeInfo_Value for start pos2 + offset --(using only media_offset at the moment) offset1 = (user_offset2 + media_offset + rd_offset2) --region_length = (rgnend-rgnpos) --Msg("region_number ".. region_number) --Msg("color ".. color) --Msg("region_length ".. region_length) --get_tempo_markers() if line[col_pattern] == "Shot" then playrate = (tempo / bb_bpm) reaper.SetMediaItemTakeInfo_Value( take, "D_PLAYRATE", playrate2 ) reaper.SetMediaItemTakeInfo_Value( take, "D_STARTOFFS", bar_pos_start + offset1 ) reaper.SetMediaItemLength(imported_drums, region_length, 0) reaper.SetMediaItemTakeInfo_Value( take, "I_CUSTOMCOLOR", color ) end if line[col_pattern] == "pattern" then --Msg("color".. color) -- Msg("region_length ".. region_length) playrate2 = (tempo / bb_bpm) reaper.SetMediaItemTakeInfo_Value( take, "D_PLAYRATE", playrate2 ) reaper.SetMediaItemTakeInfo_Value( take, "D_STARTOFFS", pos2 + offset1 ) reaper.SetMediaItemLength(imported_drums, region_length, 0) reaper.SetMediaItemTakeInfo_Value( take, "I_CUSTOMCOLOR", color ) end if consecutive == 1 then reaper.SetEditCurPos(iPosOut, 0, 0) commandID7 = reaper.NamedCommandLookup("_RSa269108c0ba744d947b179c93a57c34399b55a43") reaper.Main_OnCommand(commandID7, 0) -- Script: ReaTrak Go to start of previous region.lua --reaper.Main_OnCommand(41801, 0) -- Regions: Go to previous region after current region finishes playing (smooth seek) end commandID3 = reaper.NamedCommandLookup("_RSce47da3c9b1238de71cc94a1cb99732b9abd5e41") reaper.Main_OnCommand(commandID3, 0) -- Script: ReaTrak Go to start of next region.lua --reaper.GoToRegion(0, region_number +1, true) if region_number < num_regionsOut then loop_stuck = loop_stuck + 1 --Msg("goto enu 2nd last") --Msg("region_number ".. region_number) region_number = region_number +1 goto enum_regions end if region_number -1 == num_regionsOut then goto finish -- num_regionsOut --if region_number < num_regionsOut then --drum_pattern() --region_number = region_number +1 end end --end --if region_number >= num_regionsOut then goto finish end -- num_regionsOut --if region_number < num_regionsOut then goto start_match end end --if region_number > region_count then goto finish end --Bars to time --pos2 = ((((pos) * beat_per_measure)/ bpm) * 60) --len2 = (((len * beat_per_measure)/ bpm) * 60) --reaper.AddProjectMarker2( 0, true, pos2,pos2 + len2, "", -1, color ) end end if region_number < num_regionsOut then loop_stuck = loop_stuck + 1 --region_number = region_number + 1 --Msg("goto enu last") --Msg("region_number ".. region_number) --Msg("enu last region_number ".. region_number) region_number = previous_region _, _, pos_previous, _, _, _, _ = reaper.EnumProjectMarkers3(0, region_number) reaper.SetEditCurPos(pos_previous, 1, 0) goto enum_regions end --if region_number >= num_regionsOut then goto finish end -- num_regionsOut --Msg("Due to > (2nd bottom) ") goto finish --end ::finish:: --Msg("Finish Region ".. region_number .." of ".. region_count) --if region_number < num_regionsOut -1 then loop_stuck = loop_stuck + 1 goto enum_regions end --Msg("Final Finish") end -- INIT goto choose ::choose:: retval, filetxt = reaper.GetUserFileNameForRead("", "Import markers and regions", "txt") folder = filetxt:match[[^@?(.*[\/])[^\/]-$]] --txt_filename2 = filetxt:gsub[[^@?(.*[\/])[^\/]-$]] --Msg("Folder "..folder) --Msg("Filename "..txt_filename2) --[[ os_type = reaper.GetOS() -- "Mac OSX" -- "Win64" -- --slash = string.match(os_type, "Win") and "\\" or "/" if os_type ~= "Win32" and os_type ~= "Win64" then --Mac OS dir1 = string.gsub(filetxt, "/[^/]*$", "") dir = directory1 .."/" txt_filename1 = string.match(filetxt, "/[^/]*$") txt_filename = string.gsub(txt_filename, "/", "") txt_filename_folder = string.gsub(wavename2, "_.*", "") -- remove _ and text after it blank_ext = string.gsub(txt_filename, ".txt", "") dir_back1 = string.gsub(dir1,"(.*)/.*$","%1") dir_back2 = string.gsub(dir_back1,"(.*)/.*$","%1") dir_back = dir_back1 .."/" txt_filename_folder = txt_filename_folder2 .."/" --Needs root drum name from txt wavname=***** else --Win OS dir1 = string.gsub(filetxt, "\\[^\\]*$", "") dir = dir1 .."\\" txt_filename1 = string.match(filetxt, "\\[^\\]*$") txt_filename = string.gsub(txt_filename1, "\\", "") txt_filename_folder = string.gsub(wavename2, "_.*", "") -- remove _ and text after it blank_ext = string.gsub(txt_filename, ".txt", "") dir_back1 = string.gsub(dir1,"(.*)\\.*$","%1") dir_back2 = string.gsub(dir_back1,"(.*)\\.*$","%1") dir_back = dir_back1 .."\\" txt_filename_folder2 = txt_filename_folder .."\\" --open_file = dir .. "ModCountry16ths^_080_Style.wav" --blank_ext .. realdrums_extension --open_file_back = dir_back .. wavename --dir1_back .. blank_ext .. realdrums_extension --use in function to check dir ot dir_back --check_path = reaper.file_exists(open_file) --check_path = reaper.file_exists(open_file_back) end --]] --slash = "/" --string.match(os_type, "Win") and "\\" or "/" --Msg("Folder ".. directory) --Msg("Filename1 ".. txt_filename1) --Msg("Filename ".. txt_filename) if retval then reaper.PreventUIRefresh(1) reaper.Undo_BeginBlock() -- Begining of the undo block. Leave it at the top of your main function. reaper.ClearConsole() --read_lines_details(filetxt) read_lines(filetxt) drum_pattern() if regions_saved == 1 then commandID1 = reaper.NamedCommandLookup("_RS1c82e587d259e8ea79f40a64b7a92feb8450e477") reaper.Main_OnCommand(commandID1, 0) -- Script: ReaTrak Import regions from file.lua end reaper.SetEditCurPos(org_cur_pos, 1, 0) --last_action = reaper.Undo_CanUndo2(0) Msg("Last Action ".. last_action) reaper.Undo_EndBlock("ReaTrak fit biab drums to regions", -1) -- End of the undo block. Leave it at the bottom of your main function. reaper.UpdateArrange() reaper.PreventUIRefresh(-1) end ::finish2::