From 8869a875727401b651d2ea7082320685984a1e87 Mon Sep 17 00:00:00 2001 From: Bjarki Hall Date: Tue, 30 Dec 2025 04:39:25 +0000 Subject: [PATCH 1/4] fix midi item length not respected --- ...ted items as MIDI files into project path.lua | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/MIDI/mpl_Export selected items as MIDI files into project path.lua b/MIDI/mpl_Export selected items as MIDI files into project path.lua index 1a6f8bc1..85ae42f6 100644 --- a/MIDI/mpl_Export selected items as MIDI files into project path.lua +++ b/MIDI/mpl_Export selected items as MIDI files into project path.lua @@ -117,9 +117,19 @@ end end - -- all note off - local ppq_cur = t[#t].ppq_pos - str = str..string.pack("i4Bs4", 0, t[#t].flags&0xF , t[#t].msg1) + -- all note off - place at item end to respect item length including silence + local item_len = GetMediaItemInfo_Value(tk_t.item, 'D_LENGTH') + local item_pos = GetMediaItemInfo_Value(tk_t.item, 'D_POSITION') + local take_start_offset = GetMediaItemTakeInfo_Value(take, 'D_STARTOFFS') + local qn_start = TimeMap2_timeToQN(nil, item_pos - take_start_offset) + local qn_end = TimeMap2_timeToQN(nil, item_pos + item_len - take_start_offset) + local ppq_start = MIDI_GetPPQPosFromProjQN(take, qn_start) + local ppq_end = MIDI_GetPPQPosFromProjQN(take, qn_end) + local item_len_ppq = ppq_end - ppq_start + + local ppq_cur = math.max(t[#t].ppq_pos, item_len_ppq) + local offset_to_end = ppq_cur - ppq_last + str = str..string.pack("i4Bs4", offset_to_end, t[#t].flags&0xF , t[#t].msg1) -- set / sort if tk_t.src_events then From c5f627a510de2ca34ff5ecb7483faa6767aebf8a Mon Sep 17 00:00:00 2001 From: Bjarki Hall Date: Tue, 30 Dec 2025 04:40:32 +0000 Subject: [PATCH 2/4] fix preserve selection --- ... selected items as MIDI files into project path.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/MIDI/mpl_Export selected items as MIDI files into project path.lua b/MIDI/mpl_Export selected items as MIDI files into project path.lua index 85ae42f6..2f8b4972 100644 --- a/MIDI/mpl_Export selected items as MIDI files into project path.lua +++ b/MIDI/mpl_Export selected items as MIDI files into project path.lua @@ -33,9 +33,11 @@ --------------------------------------------------------------------- function main() - -- collect takes + -- collect takes and preserve selection + local selected_items = {} for i =1 , CountSelectedMediaItems(0)do local item = GetSelectedMediaItem(0,i-1) + selected_items[#selected_items+1] = item local take = GetActiveTake(item) local retval, tkname = GetSetMediaItemTakeInfo_String( take, 'P_NAME', '', false ) local track = GetMediaItemTrack( item ) @@ -67,6 +69,12 @@ -- export to midi file for i =1, #DATA2.takes do DATA2:ExportMIDIFiles(DATA2.takes[i]) end + + -- restore selection + for i = 1, #selected_items do + SetMediaItemSelected(selected_items[i], true) + end + UpdateArrange() end --------------------------------------------------------------------- function DATA2:MIDIEditor_SetEvts(tk_t) From c3a948ba50548de0260773151c754b80a9f5b8a9 Mon Sep 17 00:00:00 2001 From: Bjarki Hall Date: Fri, 2 Jan 2026 21:26:19 +0000 Subject: [PATCH 3/4] fix: enhance filename sanitization and handle missing item length in MIDI export --- ... items as MIDI files into project path.lua | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/MIDI/mpl_Export selected items as MIDI files into project path.lua b/MIDI/mpl_Export selected items as MIDI files into project path.lua index 2f8b4972..8d0752d7 100644 --- a/MIDI/mpl_Export selected items as MIDI files into project path.lua +++ b/MIDI/mpl_Export selected items as MIDI files into project path.lua @@ -44,9 +44,14 @@ local retval, trname = GetTrackName( track ) if DATA2.getitemname == true then name = tkname + if name == '' or not name then name = trname end + if name == '' or not name then name = 'untitled' end else name = trname + if name == '' or not name then name = 'untitled' end end + -- sanitize filename + name = name:gsub('[\\/:*?"<>|]', '_') if take and ValidatePtr2( 0, take, 'MediaItem_Take*' ) and TakeIsMIDI(take) then DATA2.takes[#DATA2.takes+1] = { @@ -99,7 +104,7 @@ end -- cc envelopes - local CCt = tk_t.CCt + local CCt = tk_t.CCt or {} for lane in pairs(CCt) do for i = 1, #CCt[lane] do local env_t = CCt[lane] @@ -126,18 +131,24 @@ end -- all note off - place at item end to respect item length including silence - local item_len = GetMediaItemInfo_Value(tk_t.item, 'D_LENGTH') - local item_pos = GetMediaItemInfo_Value(tk_t.item, 'D_POSITION') - local take_start_offset = GetMediaItemTakeInfo_Value(take, 'D_STARTOFFS') - local qn_start = TimeMap2_timeToQN(nil, item_pos - take_start_offset) - local qn_end = TimeMap2_timeToQN(nil, item_pos + item_len - take_start_offset) - local ppq_start = MIDI_GetPPQPosFromProjQN(take, qn_start) - local ppq_end = MIDI_GetPPQPosFromProjQN(take, qn_end) - local item_len_ppq = ppq_end - ppq_start - - local ppq_cur = math.max(t[#t].ppq_pos, item_len_ppq) - local offset_to_end = ppq_cur - ppq_last - str = str..string.pack("i4Bs4", offset_to_end, t[#t].flags&0xF , t[#t].msg1) + if #t > 0 and tk_t.item and take then + local item_len = GetMediaItemInfo_Value(tk_t.item, 'D_LENGTH') + local item_pos = GetMediaItemInfo_Value(tk_t.item, 'D_POSITION') + local take_start_offset = GetMediaItemTakeInfo_Value(take, 'D_STARTOFFS') + if item_len and item_pos and take_start_offset then + local qn_start = TimeMap2_timeToQN(nil, item_pos - take_start_offset) + local qn_end = TimeMap2_timeToQN(nil, item_pos + item_len - take_start_offset) + local ppq_start = MIDI_GetPPQPosFromProjQN(take, qn_start) + local ppq_end = MIDI_GetPPQPosFromProjQN(take, qn_end) + local item_len_ppq = ppq_end - ppq_start + + local ppq_cur = math.max(t[#t].ppq_pos, item_len_ppq) + local offset_to_end = ppq_cur - ppq_last + str = str..string.pack("i4Bs4", offset_to_end, t[#t].flags&0xF , t[#t].msg1) + else + str = str..string.pack("i4Bs4", 0, t[#t].flags&0xF , t[#t].msg1) + end + end -- set / sort if tk_t.src_events then From b9e6961916edcaa9ac999580dd99dedb05dd5c1c Mon Sep 17 00:00:00 2001 From: Bjarki Hall Date: Fri, 2 Jan 2026 21:31:59 +0000 Subject: [PATCH 4/4] fix: RS5K mgr handle invalid media source lengths and prevent crashes --- FX specific/mpl_RS5K_manager_functions.lua | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/FX specific/mpl_RS5K_manager_functions.lua b/FX specific/mpl_RS5K_manager_functions.lua index 308a9fee..bbbe6a16 100644 --- a/FX specific/mpl_RS5K_manager_functions.lua +++ b/FX specific/mpl_RS5K_manager_functions.lua @@ -1619,7 +1619,11 @@ end local src = PCM_Source_CreateFromFileEx(filename, true ) if not src then return end - local src_len = GetMediaSourceLength( src ) + local src_len = GetMediaSourceLength( src ) + if not src_len or src_len <= 0 then + PCM_Source_Destroy( src ) + return + end local stoffs_sec = 0 local slice_len = src_len if ignoreboundary~= true then @@ -3518,7 +3522,11 @@ end -- store external data local src = PCM_Source_CreateFromFileEx( filename, true ) if src then - local src_len = GetMediaSourceLength( src ) + local src_len = GetMediaSourceLength( src ) + if not src_len or src_len <= 0 then + PCM_Source_Destroy( src ) + return + end -- auto normalization if EXT.CONF_onadd_autoLUFSnorm_toggle == 1 then @@ -4229,8 +4237,9 @@ end function DATA:Actions_TemporaryGetAudio(filename) local PCM_Source = PCM_Source_CreateFromFile( filename ) + if not PCM_Source then return end local srclen, lengthIsQN = reaper.GetMediaSourceLength( PCM_Source ) - if srclen > EXT.CONF_crop_maxlen then + if not srclen or srclen <= 0 or srclen > EXT.CONF_crop_maxlen then --if PCM_Source then PCM_Source_Destroy( PCM_Source ) end return end @@ -4603,8 +4612,9 @@ end -- build PCM local PCM_Source = PCM_Source_CreateFromFile( filename ) + if not PCM_Source then return end local srclen, lengthIsQN = GetMediaSourceLength( PCM_Source ) - if lengthIsQN ==true or (srclen < EXT.CONF_loopcheck_minlen or srclen > EXT.CONF_loopcheck_maxlen) then + if not srclen or srclen <= 0 or lengthIsQN ==true or (srclen < EXT.CONF_loopcheck_minlen or srclen > EXT.CONF_loopcheck_maxlen) then --PCM_Source_Destroy( PCM_Source ) return end