@@ -61,44 +61,43 @@ function removeItem(item)
6161 reaper .UpdateArrange ()
6262end
6363
64- function getItemSteps (item )
64+ local function getSourceQnFromItem (item )
6565 local take = reaper .GetActiveTake (item )
66- if not take then return 0 end
66+ local src = reaper .GetMediaItemTake_Source (take )
67+ return reaper .GetMediaSourceLength (src )
68+ end
6769
68- local src = reaper .GetMediaItemTake_Source (take )
69- local srcLen = reaper .GetMediaSourceLength (src ) / 2 -- divided by 2 for mysterious reasons
70- local beatSec = reaper .TimeMap2_beatsToTime (0 , 1 ) -- 1 beat ⇒ seg
70+ -- assumes fixed BPM through the item
71+ local function getItemQn (item )
72+ local start = reaper .GetMediaItemInfo_Value (item , " D_POSITION" )
73+ local len = reaper .GetMediaItemInfo_Value (item , " D_LENGTH" )
74+ local bpm = reaper .TimeMap_GetDividedBpmAtTime (start )
75+ return len * bpm / 60 -- seconds → beats
76+ end
7177
72- return math.floor ((srcLen / beatSec ) * time_resolution + 0.5 )
78+ function getItemSteps (item )
79+ return math.floor (getSourceQnFromItem (item ) * time_resolution )
7380end
7481
7582function getItemTimes (item )
76- if not item then return 0 end
77-
78- local take = reaper .GetActiveTake (item )
79- if not take then return 1 end
80-
81- local loopSrc = reaper .GetMediaItemInfo_Value (item , " B_LOOPSRC" )
82- local srcLen = reaper .GetMediaSourceLength (reaper .GetMediaItemTake_Source (take ))
83- local itemLen = reaper .GetMediaItemInfo_Value (item , " D_LENGTH" )
83+ local sourceQn = getSourceQnFromItem (item )
84+ local itemQn = getItemQn (item )
8485
85- return math.floor (2 * itemLen / srcLen + 0.5 )
86+ return math.floor (itemQn / sourceQn + 0.5 )
8687end
8788
8889function resizeSource (item , newSteps )
89- local take = reaper .GetActiveTake (item ); if not take then return end
90- local src = reaper .GetMediaItemTake_Source (take )
91- local beatsSec = reaper .TimeMap2_beatsToTime (0 ,1 )
92- local newSrcLen = (newSteps / time_resolution ) * beatsSec * 2
93- local pos = reaper .GetMediaItemInfo_Value (item ,' D_POSITION' ) * 2
94- reaper .MIDI_SetItemExtents (item , pos , pos + newSrcLen )
90+ local itemStart = reaper .GetMediaItemInfo_Value (item , " D_POSITION" )
91+ local qnStart = reaper .TimeMap_timeToQN (itemStart )
92+ reaper .MIDI_SetItemExtents (item , qnStart , qnStart + newSteps / time_resolution )
9593end
9694
9795function resizeItem (item , times )
98- local take = reaper .GetActiveTake (item ); if not take then return end
99- local src = reaper .GetMediaItemTake_Source (take )
100- local srcLen = reaper .GetMediaSourceLength (src )
101- local newLen = srcLen * times / 2
96+ local start = reaper .GetMediaItemInfo_Value (item , " D_POSITION" )
97+ local bpm = reaper .TimeMap_GetDividedBpmAtTime (start )
98+ local sourceQn = getSourceQnFromItem (item )
99+
100+ local newLen = times * sourceQn * 60 / bpm
102101 reaper .SetMediaItemInfo_Value (item ,' D_LENGTH' , newLen )
103102 reaper .SetMediaItemInfo_Value (item ,' B_LOOPSRC' , 1 )
104103end
0 commit comments