|
|
|
11-17-2018, 02:21 AM
|
#1
|
Human being with feelings
Join Date: Jul 2009
Posts: 3,714
|
ReaScript API: Get MIDI editor on-screen layout via MIDIEditor_GetSetting_Int()
Scripts need access to the on-screen layout of the MIDI editor, in order to 1) accurately position transparent script GUIs over the editor, and to 2) quickly and accurately calculate the CC value, etc at the mouse position.
Unfortunately, REAPER's MIDI editor is secretive about its on-screen layout, with no native API functions to get information such as
* screen coordinates,
* CC lane heights,
* note vertical zoom, or
* leftmost scroll position, etc
Some of this information is supposed to be encoded in the item state chunk of the MIDI editor's active take, but it is unreliable:
* Screen coordinates are encoded in the CFGEDIT field, but it only gives the coordinates of the last-used UNmaximized size and position (and also includes the window frame).
* CC lane heights are encoded in VELLANE fields, but if two or more lanes are of the same type in the MIDI editor (for example, if two or more lanes are Pitch), only one lane is recorded in a VELLANE field. Scripts and SWS actions that try to calculate the CC lane under the mouse will fail in such situations.
Moreover, loading the item state chunk with GetItemStateChunk() is slow, which limits the responsiveness of scripts. Deferred scripts that try to load large state chunks in each defer cycle become jerky and can even slow REAPER down.
It would make scripts faster and more reliable -- and easier to code -- if REAPER could return reliable and up-to-date information about the MIDI editor's structure.
The existing API function MIDIEditor_GetSetting_Int can easily be expanded to return values such as:
* "note_zoom",
* "leftmost_pixel",
etc, and MIDIEditor_GetSetting_Str(editor, "cc_lanes", "") can return all the visible CC lanes as a single packed string.
|
|
|
11-18-2018, 08:06 AM
|
#2
|
Human being with feelings
Join Date: Dec 2017
Posts: 302
|
+1 for this additional function!
I wanted to do something like a "smart grid" for the midi editor(Ableton style). grid snap setting follow grid visibility for midi editor.
It was cool, to have horizontal and vertical zoom data for midi editor window too.
|
|
|
11-26-2018, 11:12 AM
|
#3
|
Human being with feelings
Join Date: Sep 2017
Posts: 1
|
Quote:
Originally Posted by nappies
+1 for this additional function!
I wanted to do something like a "smart grid" for the midi editor(Ableton style). grid snap setting follow grid visibility for midi editor.
It was cool, to have horizontal and vertical zoom data for midi editor window too.
|
+1
Great feature
|
|
|
12-09-2018, 08:28 AM
|
#4
|
Human being with feelings
Join Date: Dec 2017
Posts: 302
|
I made cpu save "smart" grid using JS_Mouse_GetState it works only when you zoom
by the way Ableton take much more CPU then zooming in midi editor
Last edited by nappies; 12-09-2018 at 08:58 AM.
|
|
|
12-10-2018, 08:13 AM
|
#5
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,623
|
+1
Everything that helps making programming the MIDI-Editor as versatile as the ArrangeView is a good thing.
|
|
|
01-03-2019, 10:17 PM
|
#6
|
Human being with feelings
Join Date: Apr 2011
Posts: 3,451
|
Yes please! And a GetSetArrangeView equivalent for the Midi Editor.
|
|
|
01-24-2019, 12:35 PM
|
#7
|
Human being with feelings
Join Date: Oct 2017
Location: Black Forest
Posts: 5,054
|
Quote:
Originally Posted by juliansader
The existing API function MIDIEditor_GetSetting_Int can easily be expanded to return values such as:
* "note_zoom",
* "leftmost_pixel",
etc, and MIDIEditor_GetSetting_Str(editor, "cc_lanes", "") can return all the visible CC lanes as a single packed string.
|
Yes, that would really help! Trying to get all visible CCs fails because of these missing values.
|
|
|
04-12-2019, 05:17 PM
|
#8
|
Human being with feelings
Join Date: Jul 2009
Posts: 3,714
|
Bumping this since the devs are currently working on MIDIEditor settings.
|
|
|
04-13-2019, 05:42 AM
|
#9
|
Human being with feelings
Join Date: Oct 2017
Location: Black Forest
Posts: 5,054
|
Well, I might add another thing: get and set swing amount for grid in the MIDI editor.
|
|
|
06-22-2020, 01:58 PM
|
#10
|
Human being with feelings
Join Date: Aug 2011
Posts: 517
|
+1! Please
|
|
|
06-23-2020, 01:57 AM
|
#11
|
Human being with feelings
Join Date: Nov 2010
Posts: 1,722
|
+1 please
|
|
|
06-25-2020, 12:02 PM
|
#12
|
Human being with feelings
Join Date: Jul 2009
Posts: 3,714
|
Using the ReaScriptAPI extension, one can get the positions and sizes of the MIDI editor and its child windows.
In addition, the position and name of each CC lane can be derived from the CC lane selectors, each of which is a child window of the "midipianoview" window.
The zoom, scroll and timebase settings are still hidden, though.
|
|
|
01-15-2021, 09:25 PM
|
#13
|
Human being with feelings
Join Date: Dec 2017
Location: Brazil
Posts: 1,992
|
+1
This would be gold for some projects of mine involving the piano roll !!!
|
|
|
01-17-2021, 10:31 AM
|
#14
|
Human being with feelings
Join Date: Jul 2009
Posts: 3,714
|
Quote:
Originally Posted by juliansader
In addition, the position and name of each CC lane can be derived from the CC lane selectors, each of which is a child window of the "midipianoview" window.
|
In recent versions of REAPER, the CC selection dropdowns aren't separate child windows any more, so this trick is out of the window too.
|
|
|
04-20-2021, 10:17 PM
|
#15
|
Human being with feelings
Join Date: Sep 2020
Posts: 149
|
JS_Window_GetScrollInfo can provide some information about the scroll/zoom.
It can tell you if zoom/scroll info has changed, so that you can do chunk reading only when nessesary.
Code:
VERT = {reaper.JS_Window_GetScrollInfo( midiview,"VERT")}
HORZ = {reaper.JS_Window_GetScrollInfo( midiview,"HORZ")}
retval, left, top, right, bottom = reaper.JS_Window_GetClientRect( midiview)
top_P= 127-VERT[2]/100
pixeltop = top + 62
in my notegrid hightlighting script,-I was able to estimate horizontal pixel/grid by tracking mouse movement.
The measured pixel/QN ratio was unstable, but was stablized by gathering multiple measurements into a table, and voting the most "popular" result.
I tried to estimate pixel/pitch by tracking mouse movement, but failed royally. ( update... see next post)
You have alot more limiting info to work with.
You have the top visible pitch and its pixel position.
You gather mouse y position, and its noterow or pitch position.
There might be some clever tricks you can do.
Maybe building a pixel/height function by reading the reaper.JS_Window_GetScrollInfo data.
Last edited by Malfunction; 04-21-2021 at 03:54 AM.
|
|
|
04-22-2021, 03:36 PM
|
#16
|
Human being with feelings
Join Date: Sep 2020
Posts: 149
|
This one calculates leftmostQN, rightmostQN, Qn_perPixel, PixelPrPitch, TopMostPitch, BottomMost Pitch, just from tracking mouse movement. (update: even more solid)
Code:
function main()
midiview = reaper.JS_Window_Find("midiview",false)
HORZ = {reaper.JS_Window_GetScrollInfo(midiview, "HORZ") }
VERT = {reaper.JS_Window_GetScrollInfo(midiview,"VERT")}
x, y = reaper.GetMousePosition()
X, Y = reaper.JS_Window_ScreenToClient(midiview, x, y)
retval_BR_Getmousecursorcontext , segment, details = reaper.BR_GetMouseCursorContext()
retval_BR_Getmousecursorcontext_MIDI, inlineEditor, noteRow, ccLane, ccLaneVal, ccLaneI = reaper.BR_GetMouseCursorContext_MIDI()
timepos = reaper.BR_GetMouseCursorContext_Position()
retval, left, top, right, bottom = reaper.JS_Window_GetClientRect(midiview)
top_P= 127-VERT[2]/100
pixeltop = top + 62
Y =Y - 62
if segment == "notes" then
QN = reaper.TimeMap2_timeToQN(0,timepos)
if QN >0 then
if X>max_X then
max_X = X
max_Qn = QN
end
if X<min_X then
min_X = X
min_Qn = QN
end
end
ratio = (max_X - min_X)/(max_Qn - min_Qn)
-------------------------------------------
ME_Leftmost_Qn = max_Qn - max_X /ratio
ME_Rightmost_Qn = min_Qn + ( HORZ[3]- min_X)/ratio
ME_QnPerPixel = (max_Qn - min_Qn)/(max_X - min_X)
H_zoom_ = H_zoom or 0
H_zoom = HORZ[3]
H_zoom2_ = H_zoom2 or 0
H_zoom2 = HORZ[5]
H_scroll_ = H_scroll or 0
H_scroll = HORZ[2]
if H_zoom~=H_zoom_ or H_scroll~=H_scroll_ or H_zoom2~=H_zoom2_ then
min_X = 10000
max_X = 0
end
if count<limit then
i = 4
upper_limit =100
pd = top_P-noteRow
lower_limit = Y/(pd +1)
if pd > 1 then
upper_limit = Y/(pd -1) end
if pd == 1 then
upper_limit = Y
end
i = math.floor(lower_limit-1)
while (i<upper_limit) do
if Y>=i*pd and Y<=(i*pd + i) then
if height[i] then
height[i] = height[i] + 1
else
height[i]=1
end
end
i=i+1
end
m = 0
for u,v in pairs(height) do
if v>m then
m=v
hg=u
end
end
count = count +1
end
ME_pixel_per_pitch =hg
ME_topmostPitch = top_P
ME_bottommostPitch = top_P - VERT[3]/100
V_zoom_ = V_zoom or 0
V_zoom = VERT[3]
V_scroll_ = V_scroll or 0
V_scroll = VERT[2]
if V_zoom~=V_zoom_ or V_scroll~=V_scroll_ then
count = 0
height={}
end
end
reaper.defer(main)
end
min_X = 10000
max_X = 0
height ={}
limit = 100
count = 0
main()
Last edited by Malfunction; 04-23-2021 at 07:07 PM.
|
|
|
05-01-2021, 10:45 AM
|
#17
|
Human being with feelings
Join Date: Jul 2009
Posts: 3,714
|
Quote:
Originally Posted by Malfunction
This one calculates leftmostQN, rightmostQN, Qn_perPixel, PixelPrPitch, TopMostPitch, BottomMost Pitch, just from tracking mouse movement. (update: even more solid)
|
This is an impressive function!
Unfortunately, it does not solve the problems mentioned in the OP, namely speed, reliability and ease of coding. Under the hood, the SWS function BR_GetMouseCursorContext_MIDI has to load the MIDI chunk too, so it about as slow as doing the same in a script, and it has the same limitations wrt reliability.
|
|
|
05-28-2021, 10:37 AM
|
#18
|
Human being with feelings
Join Date: Jul 2010
Location: Slovakia
Posts: 2,588
|
Bump. Also applies for notation.
|
|
|
06-23-2021, 04:45 AM
|
#19
|
Human being with feelings
Join Date: Sep 2020
Posts: 149
|
Quote:
Originally Posted by juliansader
This is an impressive function!
Unfortunately, it does not solve the problems mentioned in the OP, namely speed, reliability and ease of coding. Under the hood, the SWS function BR_GetMouseCursorContext_MIDI has to load the MIDI chunk too, so it about as slow as doing the same in a script, and it has the same limitations wrt reliability.
|
Is there a list of which functions that read from the midi chunk (itemstatechunk)?
|
|
|
12-26-2021, 08:36 AM
|
#20
|
Human being with feelings
Join Date: Jul 2010
Location: Slovakia
Posts: 2,588
|
Bump.
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 06:50 PM.
|