diff --git a/Web Interfaces/rxfx_Turing-complete.www b/Web Interfaces/rxfx_Turing-complete.www new file mode 100644 index 000000000..583e7b180 --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete.www @@ -0,0 +1,27 @@ +@description Turing-complete controller +@author Rek's Effeks +@version 0.alpha2 +@provides + [main script] rxfx_Turing-complete/rxfx_Turing-complete - Cycle track record arm.lua + [main script] rxfx_Turing-complete/rxfx_Turing-complete - Set time selection from markers.lua + [main script] rxfx_Turing-complete/rxfx_Turing-complete - New project.lua + [main script] rxfx_Turing-complete/rxfx_Turing-complete - Open selected project.lua + [main script] rxfx_Turing-complete/rxfx_Turing-complete - Read current project.lua + [main script] rxfx_Turing-complete/rxfx_Turing-complete - Rename track from ExtState.lua + [main script] rxfx_Turing-complete/rxfx_Turing-complete - Save project as.lua + [main script] rxfx_Turing-complete/rxfx_Turing-complete - Send project list.lua + [main script] rxfx_Turing-complete/rxfx_Turing-complete - Send tempo.lua + [main script] rxfx_Turing-complete/rxfx_Turing-complete - Set time signature.lua + rxfx_Turing-complete/rxfx_turing_complete.html > rxfx_turing_complete.html + rxfx_Turing-complete/OpenSans-VariableFont_wdth,wght.ttf > rxfx_turing_complete/ +@about + A web interface (adapted from fancier.html) that can fully* control Reaper. Includes project save/load, basic track management, time selection controls and various bugfixes over the original. + + NOTE: This is almost certainly not compatible with your existing workflow. It's designed to be the ONLY input method for a HEADLESS install of Reaper, specialized towards multitracking audio, and tested primarily on Raspberry Pi (Linux). This means significant caveats, including the need for a fairly specific project file structure. I have no intention of supporting midi in any form and I think it's unlikely the interface will work on Windows. + + INSTALL INSTRUCTIONS: You need to set your default project path in reaper-extstate.ini, in the form: + ``` + [Fanciest] + ProjectFolder=/path/to/folder/ + ``` + Include the slash at the end. diff --git a/Web Interfaces/rxfx_Turing-complete/OpenSans-VariableFont_wdth,wght.ttf b/Web Interfaces/rxfx_Turing-complete/OpenSans-VariableFont_wdth,wght.ttf new file mode 100644 index 000000000..9c57fbdb0 Binary files /dev/null and b/Web Interfaces/rxfx_Turing-complete/OpenSans-VariableFont_wdth,wght.ttf differ diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Cycle track record arm.lua b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Cycle track record arm.lua new file mode 100644 index 000000000..45c864639 --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Cycle track record arm.lua @@ -0,0 +1,24 @@ +-- @noindex + + +function Track_Cycle_RecordState() +--reaper.ShowConsoleMsg(reaper.GetExtState("Fanciest", "TrackRename")) +ToCycle = tonumber(reaper.GetExtState("Fanciest","TrackRecordCycle")) +Track = reaper.GetTrack(0, ToCycle-1) +if reaper.GetMediaTrackInfo_Value(Track, "I_RECARM") == 0 then + reaper.SetMediaTrackInfo_Value(Track, "I_RECARM", 1) + reaper.SetMediaTrackInfo_Value(Track, "I_RECINPUT", 0) + reaper.SetExtState("Fanciest","RecCycleSuccess","chan1",false) +else + if reaper.GetMediaTrackInfo_Value(Track, "I_RECINPUT") == 0 then + reaper.SetMediaTrackInfo_Value(Track, "I_RECINPUT", 1) + reaper.SetExtState("Fanciest","RecCycleSuccess","chan2",false) + else + reaper.SetMediaTrackInfo_Value(Track, "I_RECARM", 0) + reaper.SetExtState("Fanciest","RecCycleSuccess","off",false) + end +end +reaper.DeleteExtState("Fanciest","TrackRecordCycle",true) +end + +Track_Cycle_RecordState() diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - New project.lua b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - New project.lua new file mode 100644 index 000000000..cbf93905f --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - New project.lua @@ -0,0 +1,24 @@ +-- @noindex + + +function NewProject() + -- autosave current project + local autosaveName = reaper.GetProjectName(0):gsub(".RPP","") + if autosaveName ~= "" then + reaper.Main_SaveProject(0, false) + else + if reaper.CountMediaItems(0) ~= 0 then + reaper.SetExtState("Fanciest","ProjectSave","autosave_"..os.date(),false) + local scriptFolder = ({ reaper.get_action_context() })[2]:match('^.+[\\//]') + dofile(scriptFolder.."rxfx_Turing-complete - Save project as.lua") + end + end + + -- open selected project + local folder = reaper.GetExtState("Fanciest", "ProjectFolder") + local projectFile = reaper.GetExtState("Fanciest", "ProjectLoad") + reaper.Main_openProject("noprompt:/") + +end + +NewProject() diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Open selected project.lua b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Open selected project.lua new file mode 100644 index 000000000..b1639a207 --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Open selected project.lua @@ -0,0 +1,24 @@ +-- @noindex + + +function OpenSelectedProject() + -- autosave current project + local autosaveName = reaper.GetProjectName(0):gsub(".RPP","") + if autosaveName ~= "" then + reaper.Main_SaveProject(0, false) + else + if reaper.CountMediaItems(0) ~= 0 then + reaper.SetExtState("Fanciest","ProjectSave","autosave_"..os.date(),false) + local scriptFolder = ({ reaper.get_action_context() })[2]:match('^.+[\\//]') + dofile(scriptFolder.."rxfx_Turing-complete - Save project as.lua") + end + end + + -- open selected project + local folder = reaper.GetExtState("Fanciest", "ProjectFolder") + local projectFile = reaper.GetExtState("Fanciest", "ProjectLoad") + reaper.Main_openProject("noprompt:" .. folder .. projectFile) + +end + +OpenSelectedProject() diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Read current project.lua b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Read current project.lua new file mode 100644 index 000000000..28a3e7994 --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Read current project.lua @@ -0,0 +1,70 @@ +-- @noindex + + +function ReadCurrentProject() + -- send project name + ProjectName=reaper.GetProjectName(0) + reaper.SetExtState("Fanciest","CurrentProject",ProjectName,false) + + -- send loop points (by marker index) + local first, second = reaper.GetSet_LoopTimeRange(0, 0, 0, 0, 0) + count = reaper.GetNumRegionsOrMarkers(0) + local m, n = {}, {} + --m[0], n[0] = 0, "home" + for i=1, count do + local marker = reaper.GetRegionOrMarker(0, i-1, "") + local time = reaper.GetRegionOrMarkerInfo_Value(0, marker, "D_STARTPOS") + local idx = reaper.GetRegionOrMarkerInfo_Value(0, marker, "I_NUMBER") + m[i] = time + n[i] = idx + end + m[#m+1] = reaper.GetProjectLength(0) + n[#n+1] = "end" + m[#m+1] = 0 + n[#n+1] = "home" + + for idx, val in ipairs(m) do + if math.abs(first-val)<0.02 then + finalfirst = n[idx] + end + end + if finalfirst == nil then + reaper.GetSet_LoopTimeRange(1, 0, 0, 0, 0) + end + + for idx, val in ipairs(m) do + if math.abs(second-val)<0.02 then + finalsecond = n[idx] + end + end + if finalsecond == nil then + reaper.GetSet_LoopTimeRange(1, 0, 0, 0, 0) + end + + if finalfirst ~= finalsecond and finalfirst ~= nil and finalsecond ~= nil then + reaper.SetExtState("Fanciest","SelectDisplay",finalfirst..':'..finalsecond,false) + else + reaper.SetExtState("Fanciest","SelectDisplay","none",false) + end + + -- send track arm states + count = reaper.CountTracks(0) + local arms = {} + for i=0, count-1 do + Track = reaper.GetTrack(0, i) + if reaper.GetMediaTrackInfo_Value(Track, "I_RECARM") == 0 then + arms[i+1] = "off" + elseif reaper.GetMediaTrackInfo_Value(Track, "I_RECINPUT") == 0 then + arms[i+1] = "chan1" + elseif reaper.GetMediaTrackInfo_Value(Track, "I_RECINPUT") == 1 then + arms[i+1] = "chan2" + else + reaper.SetMediaTrackInfo_Value(Track, "I_RECARM", 0) + arms[i+1] = "off" --don't feel like dealing w weird states + end + end + armstring = table.concat(arms,":") --isnt this the guy who landed on the moon + reaper.SetExtState("Fanciest","ArmDisplay",armstring,false) +end + +ReadCurrentProject() diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Rename track from ExtState.lua b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Rename track from ExtState.lua new file mode 100644 index 000000000..e6be4abf1 --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Rename track from ExtState.lua @@ -0,0 +1,12 @@ +-- @noindex + + +function Rename_From_ExtState() +--reaper.ShowConsoleMsg(reaper.GetExtState("Fanciest", "TrackRename")) +NewName = reaper.GetExtState("Fanciest","TrackRename") +Track = reaper.GetSelectedTrack(0, 0) +reaper.GetSetMediaTrackInfo_String(Track, "P_NAME", NewName, true) +reaper.DeleteExtState("Fanciest","TrackRename",true) +end + +Rename_From_ExtState() diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Save project as.lua b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Save project as.lua new file mode 100644 index 000000000..c08286916 --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Save project as.lua @@ -0,0 +1,58 @@ +-- @noindex + + +function SaveProjectAs() + local folder = reaper.GetExtState("Fanciest", "ProjectFolder") + + local oldProject = reaper.GetProjectName(0):gsub(".RPP","") + local projectFile = reaper.GetExtState("Fanciest", "ProjectSave") + reaper.Main_SaveProjectEx(0, folder .. projectFile .. ".RPP", 8) + local projectStorage = reaper.GetProjectName(0):gsub(".RPP","") + + reaper.GetSetProjectInfo_String(0, "RECORD_PATH", projectStorage, 1) + --reaper.ShowConsoleMsg('\n\n'..oldProject..'vs'..projectStorage..'\n') + os.execute('mkdir "'..folder..projectStorage..'"') + + -- move all recordings + local numItems = reaper.CountMediaItems(0) + for i=0,numItems-1 do + local currentItem = reaper.GetMediaItem(0, i) + local numTakes = reaper.GetMediaItemNumTakes(currentItem) + for n=0,numTakes-1 do + local currentTake = reaper.GetMediaItemTake(currentItem,n) + --if currentTake == nil then + if currentTake ~= nil then + local currentSource = reaper.GetMediaItemTake_Source(currentTake) + local currentFilename = reaper.GetMediaSourceFileName(currentSource):gsub(folder,'') + if currentFilename ~= '' then + local t = {} + for str in string.gmatch(currentFilename, "([^/]+)") do + table.insert(t,str) + end + local finalFilename = folder..projectStorage..'/'..t[#t] + --reaper.ShowConsoleMsg(folder..currentFilename..'\n to '..finalFilename..'\n') + os.rename(folder..currentFilename, finalFilename) + local finalSource = reaper.PCM_Source_CreateFromFile(finalFilename) + reaper.SetMediaItemTake_Source(currentTake,finalSource) + end + end + -- + -- GetMediaSourceFilename + --reaper.ShowConsoleMsg(currentShort .. '\n') + end + end + reaper.Main_SaveProject() + + --delete old project - not ideal but a missing files warning is currently unrecoverable + if oldProject ~= projectStorage then + if not os.remove(folder..oldProject) then + os.rename(folder..oldProject,folder.."orphans_"..oldProject) + end + os.remove(folder..oldProject..'.RPP') + os.remove(folder..oldProject..'.rpp') + end + + --reaper.ShowConsoleMsg(reaper.GetProjectPath()) +end + +SaveProjectAs() diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Send project list.lua b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Send project list.lua new file mode 100644 index 000000000..e07270aed --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Send project list.lua @@ -0,0 +1,28 @@ +-- @noindex + +function SendProjectList() + local folder = reaper.GetExtState("Fanciest","ProjectFolder") + local ext = "rpp" + local files = {} + project_list = {} + + local i = 0 + repeat + local file = reaper.EnumerateFiles(folder, i) + if file and file:lower():match("%." .. ext .. "$") then + table.insert(files, file) + end + i = i + 1 + until not file + + -- files now contains all .rpp filenames in that folder + for _, f in ipairs(files) do + --reaper.ShowConsoleMsg(f .. "\n") + table.insert(project_list,f) + end + checking=reaper.GetProjectName(0) + reaper.SetExtState("Fanciest", "ProjectList", table.concat(project_list, '\n'), false) + --reaper.ShowConsoleMsg(reaper.GetExtState("Fanciest","ProjectList")) +end + +SendProjectList() diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Send tempo.lua b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Send tempo.lua new file mode 100644 index 000000000..28310de4f --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Send tempo.lua @@ -0,0 +1,10 @@ +-- @noindex + + +function SendTempo() + currentPos = reaper.GetPlayPosition() + ta1, ta2, ta3, ta4, newTempo, ta5, ta6, ta7 = reaper.GetTempoTimeSigMarker(0, reaper.FindTempoTimeSigMarker(0,currentPos)) + reaper.SetExtState("Fanciest","CurrentTempo",tostring(newTempo), false) +end + +SendTempo() diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Set time selection from markers.lua b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Set time selection from markers.lua new file mode 100644 index 000000000..a3ae581a1 --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Set time selection from markers.lua @@ -0,0 +1,46 @@ +-- @noindex + + +function SetTimeSelection() + values = reaper.GetExtState("Fanciest","MarkerLoop") + local t = {} + for str in string.gmatch(values, "([^:]+)") do + table.insert(t, str) + end + ms = {} + for i=1, reaper.GetNumRegionsOrMarkers(0) do + table.insert(ms, reaper.GetRegionOrMarkerInfo_Value(0, reaper.GetRegionOrMarker(0, i-1,""), "I_NUMBER")) + end + + + if t[1] == "home" then + first = 0 + elseif t[1] == "end" then + first = reaper.GetProjectLength(0) + else + wip = tonumber(t[1]) + for i, n in ipairs(ms) do + if n == wip then + wip = reaper.GetRegionOrMarker(0, i-1,'') + end + end + first = reaper.GetRegionOrMarkerInfo_Value(0, wip, "D_STARTPOS") + end + if t[2] == "home" then + second = 0 + elseif t[2] == "end" then + second = reaper.GetProjectLength(0) + else + wip = tonumber(t[2]) + for i, n in ipairs(ms) do + if n == wip then + wip = reaper.GetRegionOrMarker(0, i-1,'') + end + end + second = reaper.GetRegionOrMarkerInfo_Value(0, wip, "D_STARTPOS") + end + reaper.GetSet_LoopTimeRange(1, 0, first, second, true) + +end + +SetTimeSelection() diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Set time signature.lua b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Set time signature.lua new file mode 100644 index 000000000..466badb8e --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_Turing-complete - Set time signature.lua @@ -0,0 +1,26 @@ +-- @noindex + + +function TimeSig() + currentPos = reaper.GetPlayPosition() + tempoString = reaper.GetExtState("Fanciest","TempoSet") + if tempoString == "" then + ta1, ta2, ta3, ta4, newTempo, ta5, ta6, ta7 = reaper.GetTempoTimeSigMarker(0, reaper.FindTempoTimeSigMarker(0,currentPos)) + else + newTempo = tonumber(tempoString) + end + + timeSigString = reaper.GetExtState("Fanciest","TimeSigSet") + if timeSigString == "" then + ta1, ta2, ta3, ta4, ta5, newTimeSigNum, newTimeSigDenom, ta7 = reaper.GetTempoTimeSigMarker(0, reaper.FindTempoTimeSigMarker(0,currentPos)) + else + newTimeSigNum,newTimeSigDenom = timeSigString:match("(.+):(.+)") + newTimeSigNum,newTimeSigDenom = tonumber(newTimeSigNum),tonumber(newTimeSigDenom) + end + --reaper.ShowConsoleMsg(reaper.FindTempoTimeSigMarker(0,5)) + reaper.SetTempoTimeSigMarker(0, reaper.FindTempoTimeSigMarker(0,currentPos), 0, -1, -1, newTempo, newTimeSigNum, newTimeSigDenom, false) + reaper.DeleteExtState("Fanciest","TempoSet",false) + reaper.DeleteExtState("Fanciest","TimeSigSet",false) +end + +TimeSig() diff --git a/Web Interfaces/rxfx_Turing-complete/rxfx_turing_complete.html b/Web Interfaces/rxfx_Turing-complete/rxfx_turing_complete.html new file mode 100644 index 000000000..c315d42c6 --- /dev/null +++ b/Web Interfaces/rxfx_Turing-complete/rxfx_turing_complete.html @@ -0,0 +1,3184 @@ + +
+ + + + +