Rayzoon Technologies LLC Forum Index Rayzoon Technologies LLC
Official Online Community & Support
 
Rayzoon Web Site

 FAQFAQ   SearchSearch   http://rayzoon.com/v-web/bulletin/bb/lm.phpMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Updated Jamstix 4 Reaper Script with T/S and Tempo (12/2025)

 
Post new topic   Reply to topic    Rayzoon Technologies LLC Forum Index -> Jamstix - General
View previous topic :: View next topic  
Author Message
Azimuth
Moderator & Beta Team
Moderator & Beta Team


Joined: 19 Nov 2010
Posts: 2131

PostPosted: Tue Dec 02, 2025 1:33 pm    Post subject: Updated Jamstix 4 Reaper Script with T/S and Tempo (12/2025) Reply with quote



The above .gif is over 2 minutes long but I wanted to show the entire process of using the script. Now if you add "<space>x/x<space>:number" after the song part name (without the quotation marks) the script will automatically add time signature markers and tempo changes at the proper locations. The script will use the previous marker's tempo or 4/4 if no time signature or tempo is specified.
I wanted to check out what it was like working with an AI assistant so I decided to try it out. This version was coded using MS Copilot so I take no credit other than guiding it with what I wanted. Hope that you can find some use for the update. Feel free to comment or make suggestions if you'd like. I'm going to delete the posts with the earlier versions since this contains the same functionality and has been reliable so far in my testing.

Code:
---------------------------------------------------------------------
-- CLEANUP: Delete all existing markers, tempo/TS markers, and regions
---------------------------------------------------------------------
local function clear_project_markers()
    -- SWS: delete all markers and regions
    local del_all_markers_regions = reaper.NamedCommandLookup("_SWSMARKERLIST9")
    if del_all_markers_regions ~= 0 then
        reaper.Main_OnCommand(del_all_markers_regions, 0)
    end

    -- SWS: delete all regions (explicit)
    local del_all_regions = reaper.NamedCommandLookup("_SWSMARKERLIST10")
    if del_all_regions ~= 0 then
        reaper.Main_OnCommand(del_all_regions, 0)
    end

    -- Delete all tempo/time signature markers
    local numTempoMarkers = reaper.CountTempoTimeSigMarkers(0)
    for i = numTempoMarkers - 1, 0, -1 do
        reaper.DeleteTempoTimeSigMarker(0, i)
    end
end

clear_project_markers()


---------------------------------------------------------------------
-- INSERT JAMSTIX MIDI AT START OF PROJECT ON NEW LAST TRACK
---------------------------------------------------------------------
local midi_path = "C:\\ProgramData\\Jamstix4\\jamstix.mid"

local track_index = reaper.CountTracks(0)
reaper.InsertTrackAtIndex(track_index, true)
local new_track = reaper.GetTrack(0, track_index)

reaper.SetOnlyTrackSelected(new_track)
reaper.SetEditCurPos(0, true, false)
reaper.InsertMedia(midi_path, 0)

-- Adjust track list windows
reaper.TrackList_AdjustWindows(false)


---------------------------------------------------------------------
-- Function: Read all markers fresh from the project (updated positions)
---------------------------------------------------------------------
local function read_markers()
    local t = {}
    local _, numMarkers, numRegions = reaper.CountProjectMarkers(0)
    local total = numMarkers + numRegions

    local function parse_marker_name(full)
        local cleaned = full:gsub("%[%d+%]", "")
        local ts = cleaned:match("(%d+/%d+)")
        local bpm = cleaned:match(":(%d+)")
        local name = cleaned
        name = name:gsub("%d+/%d+", "")
        name = name:gsub(":%d+", "")
        name = name:match("^%s*(.-)%s*$")
        return name, ts, bpm
    end

    for i = 0, total - 1 do
        local ok, isRegion, pos, _, name, idx = reaper.EnumProjectMarkers(i)
        if ok and not isRegion then
            local regionName, ts, tempoStr = parse_marker_name(name or "")
            local num, den
            if ts then
                num, den = ts:match("(%d+)/(%d+)")
                num = tonumber(num)
                den = tonumber(den)
            end
            local bpm = tempoStr and tonumber(tempoStr) or nil
            table.insert(t, {
                name   = regionName,
                pos    = pos,
                ts_num = num,
                ts_den = den,
                bpm    = bpm,
                idx    = idx
            })
        end
    end

    table.sort(t, function(a, b) return a.pos < b.pos end)
    return t
end


---------------------------------------------------------------------
-- INITIAL READ OF ALL MARKERS
---------------------------------------------------------------------
markers = read_markers()


---------------------------------------------------------------------
-- INSERT TEMPO/TIME SIGNATURE MARKERS ONE BY ONE
---------------------------------------------------------------------
local function sleep(ms)
    local t = os.clock()
    while (os.clock() - t) < (ms / 1000) do end
end

reaper.PreventUIRefresh(1)

local a = 1
while a <= #markers do
    local m = markers[a]
    local ts_num = m.ts_num or 4
    local ts_den = m.ts_den or 4

    if m.bpm then
        reaper.SetTempoTimeSigMarker(-1, -1, m.pos, -1, -1, m.bpm, ts_num, ts_den, 0)
    else
        reaper.SetTempoTimeSigMarker(-1, -1, m.pos, -1, -1, -1, ts_num, ts_den, 0)
    end

    -- 1ms delay to allow REAPER to update before next insertion
    sleep(1)

    -- Rebuild marker list to get UPDATED positions
    markers = read_markers()
    a = a + 1
end

reaper.PreventUIRefresh(-1)


---------------------------------------------------------------------
-- CONVERT ALL MARKERS TO REGIONS (SWS)
---------------------------------------------------------------------
local convert_cmd = reaper.NamedCommandLookup("_SWSMARKERLIST13")
if convert_cmd ~= 0 then
    reaper.Main_OnCommand(convert_cmd, 0)
end


---------------------------------------------------------------------
-- FORCE PROJECT VIEW/TIMELINE UPDATE
---------------------------------------------------------------------
reaper.UpdateTimeline()
reaper.UpdateArrange()


---------------------------------------------------------------------
-- CLEANUP: DELETE THE TEMPORARY TRACK AND REWIND TO START
---------------------------------------------------------------------
if new_track then
    reaper.DeleteTrack(new_track)
end

-- Rewind edit cursor to start of project
reaper.SetEditCurPos(0, true, false)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Rayzoon Technologies LLC Forum Index -> Jamstix - General All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2002 phpBB Group