Old 07-10-2019, 02:20 AM   #1
Coachz
Human being with feelings
 
Coachz's Avatar
 
Join Date: Oct 2010
Location: Charleston, SC
Posts: 12,769
Default Request for midi actions

If anyone knows how to do it, I could use 3 midi actions please.

1. opens dialog and lowers all selected midi notes velocities higher than the number entered in the dialog box (1-127) to the value entered

2. opens dialog and raises all selected midi notes velocities lower than the number entered in the dialog box (1-127) to the value entered

3. opens dialog and sets all selected midi notes velocities to the value entered in the dialog box (1-127)


Last edited by Coachz; 07-10-2019 at 03:31 AM.
Coachz is offline   Reply With Quote
Old 07-10-2019, 02:57 AM   #2
dangguidan
Human being with feelings
 
Join Date: Jan 2019
Location: China
Posts: 654
Default

Article 3, Ctrl + F2 can be achieved. Enter the key you need to define directly.

The first two, after MIDI changes pitch, do you still need to maintain the original melody or chord?
dangguidan is offline   Reply With Quote
Old 07-10-2019, 03:30 AM   #3
Coachz
Human being with feelings
 
Coachz's Avatar
 
Join Date: Oct 2010
Location: Charleston, SC
Posts: 12,769
Default

Quote:
Originally Posted by dangguidan View Post
Article 3, Ctrl + F2 can be achieved. Enter the key you need to define directly.

The first two, after MIDI changes pitch, do you still need to maintain the original melody or chord?
Sorry I was not clear. I'm referring to velocity. I'll correct my post.
Coachz is offline   Reply With Quote
Old 07-10-2019, 04:26 AM   #4
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 3,714
Default

Quote:
Originally Posted by Coachz View Post
If anyone knows how to do it, I could use 3 midi actions please.

1. opens dialog and lowers all selected midi notes velocities higher than the number entered in the dialog box (1-127) to the value entered

2. opens dialog and raises all selected midi notes velocities lower than the number entered in the dialog box (1-127) to the value entered

3. opens dialog and sets all selected midi notes velocities to the value entered in the dialog box (1-127)

This can easily be done with a short, dedicated script.

Or, use a general-purpose "Logical editor"-type script that you can keep docked somewhere, as in rule based MIDI editing / selection.

But perhaps easiest is to use REAPER's own F2 properties. To do 1) and 2), you need to run it twice: For example, to raise all selected velocities that are lower than 64, run it once with "-63", which will make all velocities lower than 64 equal to 1, and then "+63" to raise them up again.
juliansader is offline   Reply With Quote
Old 07-10-2019, 04:39 AM   #5
Coachz
Human being with feelings
 
Coachz's Avatar
 
Join Date: Oct 2010
Location: Charleston, SC
Posts: 12,769
Default

Quote:
Originally Posted by juliansader View Post
This can easily be done with a short, dedicated script.

Or, use a general-purpose "Logical editor"-type script that you can keep docked somewhere, as in rule based MIDI editing / selection.

But perhaps easiest is to use REAPER's own F2 properties. To do 1) and 2), you need to run it twice: For example, to raise all selected velocities that are lower than 64, run it once with "-63", which will make all velocities lower than 64 equal to 1, and then "+63" to raise them up again.
Can you make these 3 scripts please if they are easy?
Coachz is offline   Reply With Quote
Old 07-11-2019, 08:55 AM   #6
Coachz
Human being with feelings
 
Coachz's Avatar
 
Join Date: Oct 2010
Location: Charleston, SC
Posts: 12,769
Default

Or show me more so I can make them myself? I know some lua.
Coachz is offline   Reply With Quote
Old 07-11-2019, 02:46 PM   #7
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 3,714
Default

Here is an example of a dedicated script for setting minimum velocity:
Code:
inputOK, input = reaper.GetUserInputs("Set minimum velocity", 1, "Velocity", "1")
if inputOK and tostring(input) then
    local vel = math.max(1, math.min(127, tostring(input)//1))
    take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive())
    local MIDIOK, MIDI = reaper.MIDI_GetAllEvts(take, "")
    local strpos, ticks, t, offset, flags, msg = 1, 0, {}
    local pack, unpack = string.pack, string.unpack
    while strpos < #MIDI do
        offset, flags, msg, strpos = unpack("i4Bs4", MIDI, strpos)
        if flags&1 ==1 and #msg >= 3 and msg:byte(1)>>4 == 9 and msg:byte(3) ~= 0 then
            msg = msg:sub(1,2) .. string.char(math.max(vel, msg:byte(3)))
        end
        t[#t+1] = pack("i4Bs4", offset, flags, msg)
    end
    reaper.MIDI_SetAllEvts(take, table.concat(t))
    reaper.Undo_OnStateChange_Item(0, "Set velocity values", reaper.GetMediaItemTake_Item(take))
end
A more versatile approach would be to use the template script from the other thread, and change lines 8 to 12 to "if selected and velocity < XXX then velocity = XXX end" where XXX is your minimum value. You can keep the IDE with this script open and docked somewhere, and when you need to do any kind of rule-based edits of MIDI notes, just type the relevant rule and run with Ctrl+S:
Code:
take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive())
item = reaper.GetMediaItemTake_Item(take)
reaper.MIDI_DisableSort(take)
countTotal, countNotes, countCCs, countSysex = reaper.MIDI_CountEvts(take)
for i = 0, countNotes-1 do
    noteOK, selected, muted, startTick, endTick, channel, pitch, velocity = reaper.MIDI_GetNote(take, i)
    -- CHANGE THESE LINES
    if pitch > 60 then 
        selected = true
    else
        selected = false
    end
    -- UP TO HERE
    reaper.MIDI_SetNote(take, i, selected, muted, startTick, endTick, channel, pitch, velocity, true)
end
reaper.MIDI_Sort(take)
reaper.Undo_OnStateChange_Item(0, "Logical editor: notes", item)

Last edited by juliansader; 07-11-2019 at 02:55 PM.
juliansader is offline   Reply With Quote
Old 07-11-2019, 02:49 PM   #8
Coachz
Human being with feelings
 
Coachz's Avatar
 
Join Date: Oct 2010
Location: Charleston, SC
Posts: 12,769
Default

Thanks very much. Can't wait to try it.
Coachz is offline   Reply With Quote
Old 07-12-2019, 05:11 AM   #9
Coachz
Human being with feelings
 
Coachz's Avatar
 
Join Date: Oct 2010
Location: Charleston, SC
Posts: 12,769
Default

Quote:
Originally Posted by juliansader View Post
Here is an example of a dedicated script for setting minimum velocity:
Code:
inputOK, input = reaper.GetUserInputs("Set minimum velocity", 1, "Velocity", "1")
if inputOK and tostring(input) then
    local vel = math.max(1, math.min(127, tostring(input)//1))
    take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive())
    local MIDIOK, MIDI = reaper.MIDI_GetAllEvts(take, "")
    local strpos, ticks, t, offset, flags, msg = 1, 0, {}
    local pack, unpack = string.pack, string.unpack
    while strpos < #MIDI do
        offset, flags, msg, strpos = unpack("i4Bs4", MIDI, strpos)
        if flags&1 ==1 and #msg >= 3 and msg:byte(1)>>4 == 9 and msg:byte(3) ~= 0 then
            msg = msg:sub(1,2) .. string.char(math.max(vel, msg:byte(3)))
        end
        t[#t+1] = pack("i4Bs4", offset, flags, msg)
    end
    reaper.MIDI_SetAllEvts(take, table.concat(t))
    reaper.Undo_OnStateChange_Item(0, "Set velocity values", reaper.GetMediaItemTake_Item(take))
end
A more versatile approach would be to use the template script from the other thread, and change lines 8 to 12 to "if selected and velocity < XXX then velocity = XXX end" where XXX is your minimum value. You can keep the IDE with this script open and docked somewhere, and when you need to do any kind of rule-based edits of MIDI notes, just type the relevant rule and run with Ctrl+S:
Code:
take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive())
item = reaper.GetMediaItemTake_Item(take)
reaper.MIDI_DisableSort(take)
countTotal, countNotes, countCCs, countSysex = reaper.MIDI_CountEvts(take)
for i = 0, countNotes-1 do
    noteOK, selected, muted, startTick, endTick, channel, pitch, velocity = reaper.MIDI_GetNote(take, i)
    -- CHANGE THESE LINES
    if pitch > 60 then 
        selected = true
    else
        selected = false
    end
    -- UP TO HERE
    reaper.MIDI_SetNote(take, i, selected, muted, startTick, endTick, channel, pitch, velocity, true)
end
reaper.MIDI_Sort(take)
reaper.Undo_OnStateChange_Item(0, "Logical editor: notes", item)
Thanks for the scripts ! The first one is great for setting a minimum velocity. Can you please tell me what to change to get 2 more scripts please ?

1. set maximum velocity

2. set all notes to velocity

I tried to figure the scripts out but the code is very cryptic. Thank you again for any help.

I'm not sure what your 2nd template script does or how it works and would probably need a licecap to show me if you are interested.
Coachz is offline   Reply With Quote
Old 07-20-2019, 03:52 AM   #10
Coachz
Human being with feelings
 
Coachz's Avatar
 
Join Date: Oct 2010
Location: Charleston, SC
Posts: 12,769
Default

Bump ? The set midi min velocity works but can anyone help me with the other two actions in the previous post please ?
Coachz is offline   Reply With Quote
Old 07-20-2019, 12:29 PM   #11
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 3,714
Default

Lua is a very simple, easy-to-learn language, and once you are familiar with the basics, it only takes a few second to change the scripts to do all kinds of nifty stuff.

To set maximum velocity:
Code:
inputOK, input = reaper.GetUserInputs("Set maximum velocity", 1, "Velocity", "1")
if inputOK and tostring(input) then
    local vel = math.max(1, math.min(127, tostring(input)//1)) -- Velocity=0 implies note-off
    take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive())
    local MIDIOK, MIDI = reaper.MIDI_GetAllEvts(take, "")
    local strpos, ticks, t, offset, flags, msg = 1, 0, {}
    local pack, unpack = string.pack, string.unpack
    while strpos < #MIDI do
        offset, flags, msg, strpos = unpack("i4Bs4", MIDI, strpos)
        if flags&1 ==1 and #msg >= 3 and msg:byte(1)>>4 == 9 and msg:byte(3) ~= 0 then -- Selected? Message includes a third byte? Event type is note-on? Velocity is not zero?
            msg = msg:sub(1,2) .. string.char(math.min(vel, msg:byte(3)))
        end
        t[#t+1] = pack("i4Bs4", offset, flags, msg)
    end
    reaper.MIDI_SetAllEvts(take, table.concat(t))
    reaper.Undo_OnStateChange_Item(0, "Set velocity values", reaper.GetMediaItemTake_Item(take))
end
To set a specific value: (Note that REAPER's native Properties dialog can do this just as easily.)
Code:
inputOK, input = reaper.GetUserInputs("Set velocity", 1, "Velocity", "1")
if inputOK and tostring(input) then
    local vel = math.max(1, math.min(127, tostring(input)//1))
    take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive())
    local MIDIOK, MIDI = reaper.MIDI_GetAllEvts(take, "")
    local strpos, ticks, t, offset, flags, msg = 1, 0, {}
    local pack, unpack = string.pack, string.unpack
    while strpos < #MIDI do
        offset, flags, msg, strpos = unpack("i4Bs4", MIDI, strpos)
        if flags&1 ==1 and #msg >= 3 and msg:byte(1)>>4 == 9 and msg:byte(3) ~= 0 then
            msg = msg:sub(1,2) .. string.char(vel)
        end
        t[#t+1] = pack("i4Bs4", offset, flags, msg)
    end
    reaper.MIDI_SetAllEvts(take, table.concat(t))
    reaper.Undo_OnStateChange_Item(0, "Set velocity values", reaper.GetMediaItemTake_Item(take))
end
Using the alternative template, to set a maximum velocity:
Code:
take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive())
item = reaper.GetMediaItemTake_Item(take)
reaper.MIDI_DisableSort(take)
countTotal, countNotes, countCCs, countSysex = reaper.MIDI_CountEvts(take)
for i = 0, countNotes-1 do
    noteOK, selected, muted, startTick, endTick, channel, pitch, velocity = reaper.MIDI_GetNote(take, i)
    -- CHANGE THESE LINES
    velocity = math.min(XXXX, velocity) -- Set XXXX as maximum velocity
    -- UP TO HERE
    reaper.MIDI_SetNote(take, i, selected, muted, startTick, endTick, channel, pitch, velocity, true)
end
reaper.MIDI_Sort(take)
reaper.Undo_OnStateChange_Item(0, "Logical editor: notes", item)
To set all velocities equal:
Code:
take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive())
item = reaper.GetMediaItemTake_Item(take)
reaper.MIDI_DisableSort(take)
countTotal, countNotes, countCCs, countSysex = reaper.MIDI_CountEvts(take)
for i = 0, countNotes-1 do
    noteOK, selected, muted, startTick, endTick, channel, pitch, velocity = reaper.MIDI_GetNote(take, i)
    -- CHANGE THESE LINES
    velocity = XXXX -- Set all velocities equal to XXXX
    -- UP TO HERE
    reaper.MIDI_SetNote(take, i, selected, muted, startTick, endTick, channel, pitch, velocity, true)
end
reaper.MIDI_Sort(take)
reaper.Undo_OnStateChange_Item(0, "Logical editor: notes", item)
juliansader is offline   Reply With Quote
Old 07-20-2019, 12:59 PM   #12
Coachz
Human being with feelings
 
Coachz's Avatar
 
Join Date: Oct 2010
Location: Charleston, SC
Posts: 12,769
Default

That is awesome. Thanks a lot juliansader ! This will be a huge help. I have posted the lua files here if you don't mind. You rock !

Set minimum velocity


Set maximum velocity


Set all to one velocity

Last edited by Coachz; 08-15-2023 at 07:04 AM.
Coachz 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 07:22 AM.


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