Skip to content

Commit f3005e2

Browse files
authored
Release Turing-complete controller v0.alpha2 (#1715)
1 parent a19b79f commit f3005e2

13 files changed

Lines changed: 3533 additions & 0 deletions
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@description Turing-complete controller
2+
@author Rek's Effeks
3+
@version 0.alpha2
4+
@provides
5+
[main script] rxfx_Turing-complete/rxfx_Turing-complete - Cycle track record arm.lua
6+
[main script] rxfx_Turing-complete/rxfx_Turing-complete - Set time selection from markers.lua
7+
[main script] rxfx_Turing-complete/rxfx_Turing-complete - New project.lua
8+
[main script] rxfx_Turing-complete/rxfx_Turing-complete - Open selected project.lua
9+
[main script] rxfx_Turing-complete/rxfx_Turing-complete - Read current project.lua
10+
[main script] rxfx_Turing-complete/rxfx_Turing-complete - Rename track from ExtState.lua
11+
[main script] rxfx_Turing-complete/rxfx_Turing-complete - Save project as.lua
12+
[main script] rxfx_Turing-complete/rxfx_Turing-complete - Send project list.lua
13+
[main script] rxfx_Turing-complete/rxfx_Turing-complete - Send tempo.lua
14+
[main script] rxfx_Turing-complete/rxfx_Turing-complete - Set time signature.lua
15+
rxfx_Turing-complete/rxfx_turing_complete.html > rxfx_turing_complete.html
16+
rxfx_Turing-complete/OpenSans-VariableFont_wdth,wght.ttf > rxfx_turing_complete/
17+
@about
18+
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.
19+
20+
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.
21+
22+
INSTALL INSTRUCTIONS: You need to set your default project path in reaper-extstate.ini, in the form:
23+
```
24+
[Fanciest]
25+
ProjectFolder=/path/to/folder/
26+
```
27+
Include the slash at the end.
Binary file not shown.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
-- @noindex
2+
3+
4+
function Track_Cycle_RecordState()
5+
--reaper.ShowConsoleMsg(reaper.GetExtState("Fanciest", "TrackRename"))
6+
ToCycle = tonumber(reaper.GetExtState("Fanciest","TrackRecordCycle"))
7+
Track = reaper.GetTrack(0, ToCycle-1)
8+
if reaper.GetMediaTrackInfo_Value(Track, "I_RECARM") == 0 then
9+
reaper.SetMediaTrackInfo_Value(Track, "I_RECARM", 1)
10+
reaper.SetMediaTrackInfo_Value(Track, "I_RECINPUT", 0)
11+
reaper.SetExtState("Fanciest","RecCycleSuccess","chan1",false)
12+
else
13+
if reaper.GetMediaTrackInfo_Value(Track, "I_RECINPUT") == 0 then
14+
reaper.SetMediaTrackInfo_Value(Track, "I_RECINPUT", 1)
15+
reaper.SetExtState("Fanciest","RecCycleSuccess","chan2",false)
16+
else
17+
reaper.SetMediaTrackInfo_Value(Track, "I_RECARM", 0)
18+
reaper.SetExtState("Fanciest","RecCycleSuccess","off",false)
19+
end
20+
end
21+
reaper.DeleteExtState("Fanciest","TrackRecordCycle",true)
22+
end
23+
24+
Track_Cycle_RecordState()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
-- @noindex
2+
3+
4+
function NewProject()
5+
-- autosave current project
6+
local autosaveName = reaper.GetProjectName(0):gsub(".RPP","")
7+
if autosaveName ~= "" then
8+
reaper.Main_SaveProject(0, false)
9+
else
10+
if reaper.CountMediaItems(0) ~= 0 then
11+
reaper.SetExtState("Fanciest","ProjectSave","autosave_"..os.date(),false)
12+
local scriptFolder = ({ reaper.get_action_context() })[2]:match('^.+[\\//]')
13+
dofile(scriptFolder.."rxfx_Turing-complete - Save project as.lua")
14+
end
15+
end
16+
17+
-- open selected project
18+
local folder = reaper.GetExtState("Fanciest", "ProjectFolder")
19+
local projectFile = reaper.GetExtState("Fanciest", "ProjectLoad")
20+
reaper.Main_openProject("noprompt:/")
21+
22+
end
23+
24+
NewProject()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
-- @noindex
2+
3+
4+
function OpenSelectedProject()
5+
-- autosave current project
6+
local autosaveName = reaper.GetProjectName(0):gsub(".RPP","")
7+
if autosaveName ~= "" then
8+
reaper.Main_SaveProject(0, false)
9+
else
10+
if reaper.CountMediaItems(0) ~= 0 then
11+
reaper.SetExtState("Fanciest","ProjectSave","autosave_"..os.date(),false)
12+
local scriptFolder = ({ reaper.get_action_context() })[2]:match('^.+[\\//]')
13+
dofile(scriptFolder.."rxfx_Turing-complete - Save project as.lua")
14+
end
15+
end
16+
17+
-- open selected project
18+
local folder = reaper.GetExtState("Fanciest", "ProjectFolder")
19+
local projectFile = reaper.GetExtState("Fanciest", "ProjectLoad")
20+
reaper.Main_openProject("noprompt:" .. folder .. projectFile)
21+
22+
end
23+
24+
OpenSelectedProject()
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
-- @noindex
2+
3+
4+
function ReadCurrentProject()
5+
-- send project name
6+
ProjectName=reaper.GetProjectName(0)
7+
reaper.SetExtState("Fanciest","CurrentProject",ProjectName,false)
8+
9+
-- send loop points (by marker index)
10+
local first, second = reaper.GetSet_LoopTimeRange(0, 0, 0, 0, 0)
11+
count = reaper.GetNumRegionsOrMarkers(0)
12+
local m, n = {}, {}
13+
--m[0], n[0] = 0, "home"
14+
for i=1, count do
15+
local marker = reaper.GetRegionOrMarker(0, i-1, "")
16+
local time = reaper.GetRegionOrMarkerInfo_Value(0, marker, "D_STARTPOS")
17+
local idx = reaper.GetRegionOrMarkerInfo_Value(0, marker, "I_NUMBER")
18+
m[i] = time
19+
n[i] = idx
20+
end
21+
m[#m+1] = reaper.GetProjectLength(0)
22+
n[#n+1] = "end"
23+
m[#m+1] = 0
24+
n[#n+1] = "home"
25+
26+
for idx, val in ipairs(m) do
27+
if math.abs(first-val)<0.02 then
28+
finalfirst = n[idx]
29+
end
30+
end
31+
if finalfirst == nil then
32+
reaper.GetSet_LoopTimeRange(1, 0, 0, 0, 0)
33+
end
34+
35+
for idx, val in ipairs(m) do
36+
if math.abs(second-val)<0.02 then
37+
finalsecond = n[idx]
38+
end
39+
end
40+
if finalsecond == nil then
41+
reaper.GetSet_LoopTimeRange(1, 0, 0, 0, 0)
42+
end
43+
44+
if finalfirst ~= finalsecond and finalfirst ~= nil and finalsecond ~= nil then
45+
reaper.SetExtState("Fanciest","SelectDisplay",finalfirst..':'..finalsecond,false)
46+
else
47+
reaper.SetExtState("Fanciest","SelectDisplay","none",false)
48+
end
49+
50+
-- send track arm states
51+
count = reaper.CountTracks(0)
52+
local arms = {}
53+
for i=0, count-1 do
54+
Track = reaper.GetTrack(0, i)
55+
if reaper.GetMediaTrackInfo_Value(Track, "I_RECARM") == 0 then
56+
arms[i+1] = "off"
57+
elseif reaper.GetMediaTrackInfo_Value(Track, "I_RECINPUT") == 0 then
58+
arms[i+1] = "chan1"
59+
elseif reaper.GetMediaTrackInfo_Value(Track, "I_RECINPUT") == 1 then
60+
arms[i+1] = "chan2"
61+
else
62+
reaper.SetMediaTrackInfo_Value(Track, "I_RECARM", 0)
63+
arms[i+1] = "off" --don't feel like dealing w weird states
64+
end
65+
end
66+
armstring = table.concat(arms,":") --isnt this the guy who landed on the moon
67+
reaper.SetExtState("Fanciest","ArmDisplay",armstring,false)
68+
end
69+
70+
ReadCurrentProject()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-- @noindex
2+
3+
4+
function Rename_From_ExtState()
5+
--reaper.ShowConsoleMsg(reaper.GetExtState("Fanciest", "TrackRename"))
6+
NewName = reaper.GetExtState("Fanciest","TrackRename")
7+
Track = reaper.GetSelectedTrack(0, 0)
8+
reaper.GetSetMediaTrackInfo_String(Track, "P_NAME", NewName, true)
9+
reaper.DeleteExtState("Fanciest","TrackRename",true)
10+
end
11+
12+
Rename_From_ExtState()
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
-- @noindex
2+
3+
4+
function SaveProjectAs()
5+
local folder = reaper.GetExtState("Fanciest", "ProjectFolder")
6+
7+
local oldProject = reaper.GetProjectName(0):gsub(".RPP","")
8+
local projectFile = reaper.GetExtState("Fanciest", "ProjectSave")
9+
reaper.Main_SaveProjectEx(0, folder .. projectFile .. ".RPP", 8)
10+
local projectStorage = reaper.GetProjectName(0):gsub(".RPP","")
11+
12+
reaper.GetSetProjectInfo_String(0, "RECORD_PATH", projectStorage, 1)
13+
--reaper.ShowConsoleMsg('\n\n'..oldProject..'vs'..projectStorage..'\n')
14+
os.execute('mkdir "'..folder..projectStorage..'"')
15+
16+
-- move all recordings
17+
local numItems = reaper.CountMediaItems(0)
18+
for i=0,numItems-1 do
19+
local currentItem = reaper.GetMediaItem(0, i)
20+
local numTakes = reaper.GetMediaItemNumTakes(currentItem)
21+
for n=0,numTakes-1 do
22+
local currentTake = reaper.GetMediaItemTake(currentItem,n)
23+
--if currentTake == nil then
24+
if currentTake ~= nil then
25+
local currentSource = reaper.GetMediaItemTake_Source(currentTake)
26+
local currentFilename = reaper.GetMediaSourceFileName(currentSource):gsub(folder,'')
27+
if currentFilename ~= '' then
28+
local t = {}
29+
for str in string.gmatch(currentFilename, "([^/]+)") do
30+
table.insert(t,str)
31+
end
32+
local finalFilename = folder..projectStorage..'/'..t[#t]
33+
--reaper.ShowConsoleMsg(folder..currentFilename..'\n to '..finalFilename..'\n')
34+
os.rename(folder..currentFilename, finalFilename)
35+
local finalSource = reaper.PCM_Source_CreateFromFile(finalFilename)
36+
reaper.SetMediaItemTake_Source(currentTake,finalSource)
37+
end
38+
end
39+
--
40+
-- GetMediaSourceFilename
41+
--reaper.ShowConsoleMsg(currentShort .. '\n')
42+
end
43+
end
44+
reaper.Main_SaveProject()
45+
46+
--delete old project - not ideal but a missing files warning is currently unrecoverable
47+
if oldProject ~= projectStorage then
48+
if not os.remove(folder..oldProject) then
49+
os.rename(folder..oldProject,folder.."orphans_"..oldProject)
50+
end
51+
os.remove(folder..oldProject..'.RPP')
52+
os.remove(folder..oldProject..'.rpp')
53+
end
54+
55+
--reaper.ShowConsoleMsg(reaper.GetProjectPath())
56+
end
57+
58+
SaveProjectAs()
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-- @noindex
2+
3+
function SendProjectList()
4+
local folder = reaper.GetExtState("Fanciest","ProjectFolder")
5+
local ext = "rpp"
6+
local files = {}
7+
project_list = {}
8+
9+
local i = 0
10+
repeat
11+
local file = reaper.EnumerateFiles(folder, i)
12+
if file and file:lower():match("%." .. ext .. "$") then
13+
table.insert(files, file)
14+
end
15+
i = i + 1
16+
until not file
17+
18+
-- files now contains all .rpp filenames in that folder
19+
for _, f in ipairs(files) do
20+
--reaper.ShowConsoleMsg(f .. "\n")
21+
table.insert(project_list,f)
22+
end
23+
checking=reaper.GetProjectName(0)
24+
reaper.SetExtState("Fanciest", "ProjectList", table.concat(project_list, '\n'), false)
25+
--reaper.ShowConsoleMsg(reaper.GetExtState("Fanciest","ProjectList"))
26+
end
27+
28+
SendProjectList()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- @noindex
2+
3+
4+
function SendTempo()
5+
currentPos = reaper.GetPlayPosition()
6+
ta1, ta2, ta3, ta4, newTempo, ta5, ta6, ta7 = reaper.GetTempoTimeSigMarker(0, reaper.FindTempoTimeSigMarker(0,currentPos))
7+
reaper.SetExtState("Fanciest","CurrentTempo",tostring(newTempo), false)
8+
end
9+
10+
SendTempo()

0 commit comments

Comments
 (0)