0b091a1afd
Website: - Full homepage redesign: new hero with punchy tagline, social proof strip with real caller quotes, featured episode spotlight, clips moved up - Remove Q&A section, cover art from hero, secondary links - Fix share icon fill (currentColor), add .sr-only class - Bump cache versions to v=6 Backend: - Blacklist Celeste voice - Fix avatar gender caching with marker files - Fix _match_voices_to_styles() bypassing BLACKLISTED_VOICES Publishing: - Fix Castopod container path (/var/www/castopod/ → /app/) - Revert CLOUDFLARE_UPLOAD_LIMIT workaround (API fixed) - Publish episode 38 Reaper: - Dual silence threshold (2.5s transitions, 6s same-speaker) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
116 lines
3.4 KiB
Lua
116 lines
3.4 KiB
Lua
-- Show Region Marker — background script for REAPER
|
|
-- Polls /tmp/reaper_state.txt for state changes and creates colored regions.
|
|
-- Backend writes "dialog", "ad", or "ident" to the file.
|
|
-- Run via Actions → Run ReaScript before or during recording.
|
|
|
|
local STATE_FILE = "/tmp/reaper_state.txt"
|
|
|
|
local COLORS = {
|
|
dialog = reaper.ColorToNative(50, 180, 50) + 0x1000000, -- green
|
|
ad = reaper.ColorToNative(200, 80, 80) + 0x1000000, -- red
|
|
ident = reaper.ColorToNative(80, 120, 200) + 0x1000000, -- blue
|
|
}
|
|
local LABELS = {
|
|
dialog = "DIALOG",
|
|
ad = "AD",
|
|
ident = "IDENT",
|
|
}
|
|
|
|
local counts = { dialog = 0, ad = 0, ident = 0 }
|
|
local current_type = nil -- which region type is currently open
|
|
local current_start = 0
|
|
local last_pos = 0 -- last known transport position (while running)
|
|
local last_state = ""
|
|
local transport_active = false
|
|
|
|
local function log(msg)
|
|
reaper.ShowConsoleMsg("[Regions] " .. msg .. "\n")
|
|
end
|
|
|
|
local function is_playing_or_recording()
|
|
local state = reaper.GetPlayState()
|
|
return state > 0 and state ~= 2
|
|
end
|
|
|
|
local function open_region(rtype)
|
|
if current_type then return end
|
|
current_type = rtype
|
|
current_start = reaper.GetPlayPosition()
|
|
log("OPEN " .. rtype .. " at " .. string.format("%.2f", current_start))
|
|
end
|
|
|
|
local function close_region(pos_override)
|
|
if not current_type then return end
|
|
local pos = pos_override or reaper.GetPlayPosition()
|
|
local len = pos - current_start
|
|
local rtype = current_type
|
|
current_type = nil
|
|
log("CLOSE " .. rtype .. " at " .. string.format("%.2f", pos) .. " (len=" .. string.format("%.2f", len) .. ")")
|
|
if len > 0.1 then
|
|
counts[rtype] = counts[rtype] + 1
|
|
local name = LABELS[rtype] .. " " .. counts[rtype]
|
|
reaper.AddProjectMarker2(0, true, current_start, pos, name, -1, COLORS[rtype])
|
|
log(" -> Created '" .. name .. "'")
|
|
else
|
|
log(" -> Skipped (too short)")
|
|
end
|
|
end
|
|
|
|
local function poll()
|
|
if not transport_active then
|
|
if is_playing_or_recording() then
|
|
transport_active = true
|
|
log("Transport started at " .. string.format("%.2f", reaper.GetPlayPosition()))
|
|
local f = io.open(STATE_FILE, "r")
|
|
if f then
|
|
last_state = f:read("*l") or "dialog"
|
|
f:close()
|
|
else
|
|
last_state = "dialog"
|
|
end
|
|
log("Initial state: '" .. last_state .. "'")
|
|
open_region(last_state)
|
|
end
|
|
reaper.defer(poll)
|
|
return
|
|
end
|
|
|
|
-- Track position while transport is running
|
|
last_pos = reaper.GetPlayPosition()
|
|
|
|
-- Detect transport stop (recording ended) — use last known good position
|
|
if not is_playing_or_recording() then
|
|
log("Transport stopped at last known pos " .. string.format("%.2f", last_pos))
|
|
close_region(last_pos)
|
|
transport_active = false
|
|
reaper.defer(poll)
|
|
return
|
|
end
|
|
|
|
local f = io.open(STATE_FILE, "r")
|
|
if f then
|
|
local state = f:read("*l") or "dialog"
|
|
f:close()
|
|
|
|
if state ~= last_state then
|
|
log("State change: '" .. last_state .. "' -> '" .. state .. "'")
|
|
close_region()
|
|
open_region(state)
|
|
last_state = state
|
|
end
|
|
end
|
|
|
|
reaper.defer(poll)
|
|
end
|
|
|
|
log("Script loaded — waiting for transport to start...")
|
|
|
|
reaper.atexit(function()
|
|
log("Script stopping (atexit)")
|
|
close_region()
|
|
local total = counts.dialog + counts.ad + counts.ident
|
|
log("Done. " .. total .. " regions (" .. counts.dialog .. " dialog, " .. counts.ad .. " ad, " .. counts.ident .. " ident)")
|
|
end)
|
|
|
|
poll()
|