@@ -61,44 +61,43 @@ function removeItem(item)
61
61
reaper .UpdateArrange ()
62
62
end
63
63
64
- function getItemSteps (item )
64
+ local function getSourceQnFromItem (item )
65
65
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
67
69
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
71
77
72
- return math.floor ((srcLen / beatSec ) * time_resolution + 0.5 )
78
+ function getItemSteps (item )
79
+ return math.floor (getSourceQnFromItem (item ) * time_resolution )
73
80
end
74
81
75
82
function 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 )
84
85
85
- return math.floor (2 * itemLen / srcLen + 0.5 )
86
+ return math.floor (itemQn / sourceQn + 0.5 )
86
87
end
87
88
88
89
function 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 )
95
93
end
96
94
97
95
function 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
102
101
reaper .SetMediaItemInfo_Value (item ,' D_LENGTH' , newLen )
103
102
reaper .SetMediaItemInfo_Value (item ,' B_LOOPSRC' , 1 )
104
103
end
0 commit comments