Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER Feature Requests

Reply
 
Thread Tools Display Modes
Old 11-09-2015, 09:20 AM   #1
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default MIDI editor: API to get/set editable/visible state of items. No new features needed!

EDIT 2018-03-09:

These new API functions do not require that any new features be added to the MIDI editor -- the functions simply return information that is already visible onscreen, or automate actions that the users can themselves do by manually (and laboriously) clicking with the mouse.

In summary:

These two functions (GetItemState and SetItemState) replicate exactly how the user can see item visbility/editability in the track list, or change it by clicking on the icons:

Code:
int pianorollstate, int trackliststate = reaper.MIDIEditor_GetItemState(HWND editor, MediaItem* item)

pianorollstate: 0 = hidden, 1 = visible, 2 = editable, 3 = active, -1 = error (e.g. item not found)
trackliststate: 0 = hidden, 1 = visible, -1 = error
Code:
boolean retval = reaper.MIDIEditor_SetItemState(HWND editor, MediaItem* item, int pianorollstate, int trackliststate)

pianorollstate: 0 = hidden, 1 = visible, 2 = editable, 3 = active
trackliststate: 0 = hidden, 1 = visible

retval: returns true if successful; returns false if item does not exist or does not contain MIDI, or if trying to make item active if item is already active in another editor.  
(This return value could perhaps be an int, in order to provide more details about error.)
A potential complication is that an item's editable take in the MIDI editor does not always correspond to the active take in the arrange view. We therefore need additional functions to return the editable takes.

The easiest would be a function that returns all editable takes at once in a single table or reaper.array. However, other workable alternatives would be functions that return takes by index (similar to "GetSelectedTrack"), or that return the MIDI editor-editable/visible take per item (similar to "GetActiveTake" for the arrange view):

Code:
table reaper.MIDIEditor_GetAllEditableTakes(HWND midieditor)
table reaper.MIDIEditor_GetAllVisibleTakes(HWND midieditor)
or
Code:
MediaItem_Take reaper.MIDIEditor_GetItemVisibleTake(HWND midieditor, MediaItem item)
or
Code:
MediaItem_Take reaper.MIDIEditor_GetEditableTake(HWND midieditor, int takeidx)
MediaItem_Take reaper.MIDIEditor_GetVisibleTake(HWND midieditor, int takeidx)
End EDIT ---------------------------------



As described in this thread:
forum.cockos.com/showthread.php?p=1593929

Without access to all editable takes, user scripts cannot properly integrate with the workflow of REAPER's MIDI editor.

To quote paaltio:
Quote:
Originally Posted by paaltio View Post
This simple thing basically stands in the way of a lot of advanced MIDI workflow.
[...]
The most obvious thing would be for MIDIEditor_GetTake to have a second parameter that is an index to the editable takes,
[...]
So it'd be nice to get a confirmation from the devs whether this is coming or if we should just be actively looking for workarounds.

Last edited by juliansader; 05-06-2018 at 11:03 PM.
juliansader is online now   Reply With Quote
Old 08-14-2016, 12:30 PM   #2
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 8,043
Default

+1

I also got hit by this missing functionality when trying to do a script.

http://forum.cockos.com/showpost.php...2&postcount=10
nofish is offline   Reply With Quote
Old 12-15-2016, 10:21 PM   #3
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default

In the native workflow of the MIDI editor, users expect editing actions to apply to all editable takes, and if an action doesn't, the users may regard this as a bug (for example: Changing note channel (FIXED)). Similarly, scripts should preferably also be able to edit all editable takes.

In addition to *getting* the editable/visible state of a take, it would be super useful to be able to *set* the state via ReaScript:

My favorite application would be to provide MIDI editor "screensets": When working on large orchestral templates with >>1000 tracks, it would save a lot of clicking if users could quickly store and recall the editable/visible state of tracks. For example, single-click switching between having all strings editable and the rest of the orchestra only visible, to having all woodwinds editable and the string visible, etc.

The screensets could even work with track names and wildcards, so that they can apply to new templates without requiring new configuring.

Similarly, a function to Get/Set item visibility in the *track list* will save a lot of scrolling for projects with >>1000 tracks.

Last edited by juliansader; 03-09-2018 at 01:33 PM.
juliansader is online now   Reply With Quote
Old 12-16-2016, 10:17 AM   #4
Commala
Human being with feelings
 
Join Date: Feb 2014
Posts: 571
Default

Quote:
Originally Posted by juliansader View Post
My favorite application would be to provide MIDI editor "screensets": When working on large orchestral templates with >100 tracks, it would save a lot of clicking if users could quickly store and recall the editable/visible state of tracks. For example, single-click switching between having all strings editable and the rest of the orchestra only visible, to having all woodwinds editable and the string visible, etc.

The screensets could even work with track names and wildcards, so that they can apply to new templates without requiring new configuring.
Read my mind with this one. Now that would be useful!
Commala is offline   Reply With Quote
Old 05-09-2017, 07:57 AM   #5
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default

I am bumping this FR since the topic came up in a thread over at VI-Control forum.

There might be some kind of "trick" that will allow a script to detect editable takes, by running a native action that affects all editable takes (such as "Invert selection") and then checking all takes' MIDI hashes for changes.

Last edited by juliansader; 06-22-2017 at 05:33 AM.
juliansader is online now   Reply With Quote
Old 06-01-2017, 11:49 AM   #6
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default

I am not sure that the MIDI hashes returned by MIDI_GetHash reliably *only* change when the MIDI itself changes, but the new API function MIDI_GetAllEvts can be used similarly.

The following code implements the above-mentioned trick. It finds all editable takes that have selected notes, and stores them in a table. The keys of the table are the take handles, and the values are the MIDI strings returned by MIDI_GetAllEvts.

Code:
local tableMIDIdata = {}

-- Iterate through all takes, getting their MIDI data
for i=0, reaper.CountMediaItems(0)-1 do 

    curItem = reaper.GetMediaItem(0, i)
    if reaper.ValidatePtr2(0, curItem, "MediaItem*") then 
     
        for t=0, reaper.CountTakes(curItem)-1 do 
        
            curTake = reaper.GetTake(curItem, t)    
            if reaper.ValidatePtr2(0, curTake, "MediaItem_Take*") and reaper.TakeIsMIDI(curTake) then 
            
                -- GetAllEvts and GetHash can both be used to check for changes in MIDI data.
                -- GetAllEvts is much slower than GetHash, though.
                gotDataOK, tableMIDIdata[curTake] = reaper.MIDI_GetAllEvts(curTake, "")
                --gotDataOK, tableMIDIdata[curTake] = reaper.MIDI_GetHash(curTake, true, "")
                
            end -- if reaper.ValidatePtr2(0, curItem, "MediaItem_Take*") and reaper.TakeIsMIDI(curTake)
        end -- for t=0, numTakes-1
    end -- if reaper.ValidatePtr2(0, curItem, "MediaItem*")
end -- for i=0, numItems-1

-- Now apply some native action that is guaranteed to change something in all (relevant) editable takes.
-- (Remember that some actions are only applied to the active take, not to all editable ones.)
-- For example, here I use "Edit: Invert voicing downwards for selected notes" to find editable takes with selected notes.
-- If the script will replace the MIDI data of all takes that are changed by the native Action, there is no need to 
--    undo the Action.
-- To prevent the Action from creating an undo point, start an Undo Block before calling Action.

reaper.Undo_BeginBlock2(0)
editor = reaper.MIDIEditor_GetActive()
reaper.MIDIEditor_OnCommand(editor, 40909) -- Edit: Invert voicing downwards for selected notes (all editable)

-- Now iterate through all takes again, comparing their old and new MIDI data
for take, oldMIDIdata in pairs(tableMIDIdata) do
    local gotDataOK, newMIDIdata = reaper.MIDI_GetAllEvts(take, "")
    --local gotDataOK, newMIDIdata = reaper.MIDI_GetHash(take, true, "")
    if newMIDIdata == oldMIDIdata then
        -- If no change in take's MIDI, delete from table
        tableMIDIdata[take] = nil
    end
end

Last edited by juliansader; 07-11-2017 at 11:32 AM.
juliansader is online now   Reply With Quote
Old 06-21-2017, 03:02 PM   #7
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default

Another application of these API functions would be to temporarily toggle all non-active takes to non-visible while a MIDI editing script is running, in order to make the scripts run faster.

The MIDI editor gets bogged down significantly when multiple takes are editable or visible (a single refresh / defer cycle can sometimes take more than a second), so if all non-active takes can temporarily be removed, scripts would be much more responsive.
juliansader is online now   Reply With Quote
Old 06-26-2017, 04:23 AM   #8
Ulf3000
Human being with feelings
 
Join Date: May 2016
Posts: 336
Default

Quote:
Originally Posted by juliansader View Post
As described in this thread:
forum.cockos.com/showthread.php?p=1593929

Without access to all editable takes, user scripts cannot properly integrate with the workflow of REAPER's MIDI editor.

To quote paaltio:
Originally Posted by paaltio View Post
This simple thing basically stands in the way of a lot of advanced MIDI workflow.
[...]
The most obvious thing would be for MIDIEditor_GetTake to have a second parameter that is an index to the editable takes,
[...]
So it'd be nice to get a confirmation from the devs whether this is coming or if we should just be actively looking for workarounds.


+750 on this .. i wanted to program my first addon and directly came to this
Ulf3000 is offline   Reply With Quote
Old 08-14-2017, 02:16 PM   #9
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default

Over at the VI-Control forum, the lack of API functions and MIDI editor screensets was recently lamented:

Quote:
I'm in the process of migrating from Cubase to Reaper, and apart from a few things it's mostly a very pleasant process.

One thing, however, bugs me to no end. I Cubase I would often have a bunch of MIDI parts, say one part per section of the strings, that I would edit together in the same piano roll window. When doing that it was easy to have a hotkey that would cycle between making each of the 5 open parts active.

In Reaper it seems that this is not possible. When opening multiple parts in the MIDI editor, you have to rely on the MIDI track list for switching, but that always contains all the tracks of the project, and I've found no easy way to just cycle between the parts I've selected, making each one active while the others are visible.
Quote:
How do you guys deal with this? I find it almost unusable in an orchestral context, but would love to go "all Reaper".
Quote:
I did actually look into a scripting solution recently, but the API doesn't have functions to access to the midi track list. And it's not currently possible only show tracks in the list that the open items are on.
Oh well... The developers might one day stumble upon my feature request and decide that it's useful. One can dream...
A function to Get/Set item visibility in the *track list* will save a lot of scrolling for projects with >>100 tracks.

Last edited by juliansader; 03-08-2018 at 11:28 PM.
juliansader is online now   Reply With Quote
Old 09-16-2017, 11:04 AM   #10
marius
Human being with feelings
 
Join Date: Feb 2012
Posts: 8
Default

+1. Getting access to all visible takes in the MIDI Editor is fundamental and a sorely needed API feature! Help me finally move away from Cubase!
marius is offline   Reply With Quote
Old 09-16-2017, 04:45 PM   #11
Klangfarben
Human being with feelings
 
Join Date: Jul 2016
Posts: 287
Default

Quote:
Originally Posted by juliansader View Post
In addition to *getting* the editable/visible state of a take, it would be super useful to be able to *set* the state via ReaScript:
+1 for this. This would be massively useful for large templates.
Klangfarben is offline   Reply With Quote
Old 10-01-2017, 10:16 AM   #12
srdmusic
Human being with feelings
 
Join Date: Dec 2016
Posts: 369
Default

This is a must have. We currently can't apply scripts to multiple midi parts, which means that if I want to edit the volume of a 5 part string section I have to open each one and apply the same reduce cc vol script or redraw each one with Julian's awesome scripts. This is a huge time waster when other actions like the pencil tool work just fine.

Even actions like the native reaper quantize need to be done on a part by part basis. That's kind of ridiculous when you have 16 drum parts that need to be quantized.
srdmusic is offline   Reply With Quote
Old 12-28-2017, 11:08 AM   #13
teniente powell
Human being with feelings
 
teniente powell's Avatar
 
Join Date: Oct 2016
Location: Spain
Posts: 182
Default

A perfect request for Reaper 6. I don't remember where is the thread of wishes for Reaper 6.
teniente powell is offline   Reply With Quote
Old 03-08-2018, 11:21 AM   #14
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default

Surely it won't take Schwa more than a few minutes to write a MIDIEditor_GetEditable function that returns all editable takes in a Lua table or a reaper.array:

Code:
reaper.array MIDIEditor_GetAllEditableTakes(HWND midieditor)

Last edited by juliansader; 03-09-2018 at 12:55 AM.
juliansader is online now   Reply With Quote
Old 03-08-2018, 11:29 PM   #15
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default

Quote:
Originally Posted by srdmusic View Post
Even actions like the native reaper quantize need to be done on a part by part basis. That's kind of ridiculous when you have 16 drum parts that need to be quantized.
A combination of API functions
* MIDIEditor_GetAllEditableTakes and
* MIDIEditor_SetActiveTake
can even be used to fix native actions such as quantize that are still limited to the active take: The script will iterate through all editable takes, making each active in turn, and running the native action on that take.
juliansader is online now   Reply With Quote
Old 03-09-2018, 12:30 AM   #16
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default

In summary:

The first two functions (GetItemState and SetItemState) replicate exactly how the user can see item visbility/editability in the track list, or change it by clicking on the icons:

Code:
int pianorollstate, int trackliststate = reaper.MIDIEditor_GetItemState(HWND editor, MediaItem* item)

pianorollstate: 0 = hidden, 1 = visible, 2 = editable, 3 = active, -1 = error (e.g. item not found)
trackliststate: 0 = hidden, 1 = visible, -1 = error
Code:
boolean retval = reaper.MIDIEditor_SetItemState(HWND editor, MediaItem* item, int pianorollstate, int trackliststate)

pianorollstate: 0 = hidden, 1 = visible, 2 = editable, 3 = active
trackliststate: 0 = hidden, 1 = visible

retval: returns true if successful; returns false if item does not exist or does not contain MIDI, or if trying to make item active if item is already active in another editor.  
(This return value could perhaps be an int, in order to provide more details about error.)
A potential complication is that an item's editable take in the MIDI editor does not always correspond to the active take in the arrange view. We therefore need additional functions to return the editable/visible takes.

The easiest would be a function that returns all editable/visible takes at once in a single table or reaper.array. However, other workable alternatives would be functions that return takes by index (similar to "GetSelectedTrack"), or that return the MIDI editor-editable/visible take per item (similar to "GetActiveTake" for the arrange view):

Code:
table reaper.MIDIEditor_GetAllEditableTakes(HWND midieditor)
table reaper.MIDIEditor_GetAllVisibleTakes(HWND midieditor)
or
Code:
MediaItem_Take reaper.MIDIEditor_GetItemVisibleTake(HWND midieditor, MediaItem item)
or
Code:
MediaItem_Take reaper.MIDIEditor_GetEditableTake(HWND midieditor, int takeidx)
MediaItem_Take reaper.MIDIEditor_GetVisibleTake(HWND midieditor, int takeidx)

Last edited by juliansader; 03-09-2018 at 12:56 AM.
juliansader is online now   Reply With Quote
Old 05-01-2018, 11:13 AM   #17
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default

When working in the MIDI editor without the Track List (or if the Track List is too long and clumsy), item activation, editability and visibility can be partially controlled via the arrange view.

However, the options are rather limited, since a single value, Selection, must control at least three settings: activation, editability and visibility. If, for example, "Selection is linked to editability" then visibility cannot be changed via the arrange view. And if an item is clicked to make it active, all the other items lose their editability.

The API functions requested in this thread can make control via the arrange view must better: For example, the mouse can be swiped across multiple items while holding a shortcut (linked to a script) to make the items visible, without changing their selection.

Last edited by juliansader; 05-01-2018 at 12:13 PM.
juliansader is online now   Reply With Quote
Old 05-06-2018, 09:15 AM   #18
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 8,043
Default

bump (for the current MIDI editor foucused pre-release cycle)
nofish is offline   Reply With Quote
Old 06-11-2018, 01:32 AM   #19
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 62
Default

So, without the proposed functions, is it impossible to create an action to solo only visible tracks in the midi editor?
reapero is online now   Reply With Quote
Old 06-11-2018, 01:52 PM   #20
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 2,098
Default

Quote:
Originally Posted by reapero View Post
So, without the proposed functions, is it impossible to create an action to solo only visible tracks in the midi editor?
If your MIDI editor is set to "One MIDI editor per project" and "Selection is linked to visibility", you can probably solo the tracks with visible items by checking item selection in the arrange view.

If you are using other settings, you can use the trick that I described above to find tracks with editable items (as long as the items contain some MIDI data), but the trick will not work on items that are only visible, not editable.

Otherwise, you are out of luck, unfortunately (AFAIK).
juliansader is online now   Reply With Quote
Old 06-18-2018, 05:24 AM   #21
MorkV
Human being with feelings
 
Join Date: Jun 2016
Posts: 41
Default

Please devs, this is a much-needed extension for midi editor, especially for orchestral things.
MorkV is offline   Reply With Quote
Old 07-30-2018, 01:21 AM   #22
meradium
Human being with feelings
 
Join Date: May 2018
Posts: 38
Default

Yes absolutely! +1
meradium is offline   Reply With Quote
Old 08-06-2018, 11:55 PM   #23
meradium
Human being with feelings
 
Join Date: May 2018
Posts: 38
Default

Revisiting this: +100000...0

It's so sad that we cannot make better use of the MIDI Track List inside the MIDI Editor. When I initially saw it coming from Cubase it made me wonder what amazing things would be finally possible.

E.g. no more opening and closing multi-string parts.... Ability to quickly mute and solo individual selected instruments within (!) multiple selected MIDI parts.

I am sorry to say this, but I feel in its current form it is pretty useless and confusing. It is basically a replica of the arrangement window in small...

I already explained further in my FR linked below what would be my dream operation.

A way, either native or via a script, to toggle track visibility insider the Track List window based on what the user initially selected prior to opening the editor would boost productivity enormously.
__________________
FR: One MIDI Editor to rule them all... https://forum.cockos.com/showthread....57#post2017157
meradium is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 01:38 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.