Old 01-28-2020, 11:17 PM   #1961
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 205
Default

REQ:
Midi Editor: unselect last note (chord) in selected notes.

I thought it was a simple solution, but I could not find such scripts, and my skills are not enough to write a script myself.
cool is online now   Reply With Quote
Old 01-29-2020, 09:58 PM   #1962
MusoBob
Human being with feelings
 
MusoBob's Avatar
 
Join Date: Sep 2014
Posts: 1,266
Default

Quote:
Originally Posted by cool View Post
REQ:
Midi Editor: unselect last note (chord) in selected notes. ...
Can you post a before/after pic of what you need exactly.
__________________
ReaTrakStudio Chord Track for Reaper forum
www.reatrak.com
MusoBob is offline   Reply With Quote
Old 01-30-2020, 05:18 AM   #1963
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 205
Default

Quote:
Originally Posted by MusoBob View Post
Can you post a before/after pic of what you need exactly.
Oh, sure.

Single notes. Before using the script, I selected a few notes. After using the script, the last (rightmost) note among the selected ones became without selection

Chords - similarly, but if possible. After the script, the selection should be removed from the last (rightmost) chord.


-
-
-
-
cool is online now   Reply With Quote
Old 01-30-2020, 04:42 PM   #1964
MusoBob
Human being with feelings
 
MusoBob's Avatar
 
Join Date: Sep 2014
Posts: 1,266
Default

Try this in the MIDI Editor:
Code:
 
 ME = reaper.MIDIEditor_GetActive()

 take = reaper.MIDIEditor_GetTake(ME)
  
 retval, notecnt, ccevtcnt, textsyxevtcnt = reaper.MIDI_CountEvts( take )

 note_pos = 0

 for i = 0, notecnt -1 do
   retval, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote( take, i )
   if selected then
      
      if startppqpos >= note_pos then
         note_pos = startppqpos  
      end
   end
 end   
 
 for i = 0, notecnt -1 do
   retval, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote( take, i )
   if selected and startppqpos == note_pos then
      reaper.MIDI_SetNote( take, i  , false, muted, startppqpos, endppqpos, chan, pitch, vel, true )  
      
   end
 end
__________________
ReaTrakStudio Chord Track for Reaper forum
www.reatrak.com
MusoBob is offline   Reply With Quote
Old 01-31-2020, 12:45 AM   #1965
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 205
Default

Quote:
Originally Posted by MusoBob View Post
Try this in the MIDI Editor:
[CODE]
AMAZING, thank you!

I needed this code to create a legato script, so that the notes slightly overlap each other, but at the same time so that the last notes do not go beyond the boundaries of the item.
Finally:

Code:
    local ME = reaper.MIDIEditor_GetActive();
    if not ME then return end;

    local take = reaper.MIDIEditor_GetTake(ME);
    reaper.MIDIEditor_OnCommand(ME,reaper.NamedCommandLookup("_BR_ME_SAVE_NOTE_SEL_SLOT_1"));--Save note selection
    reaper.Undo_BeginBlock();
    reaper.PreventUIRefresh(1);


local correct
if reaper.GetToggleCommandStateEx(32060, 40681) == 1 then
   reaper.MIDIEditor_LastFocused_OnCommand(40681,0) --Options: Correct overlapping notes while editing
   correct = 1
end



ME = reaper.MIDIEditor_GetActive()

 take = reaper.MIDIEditor_GetTake(ME)
  
 retval, notecnt, ccevtcnt, textsyxevtcnt = reaper.MIDI_CountEvts( take )

 note_pos = 0

 for i = 0, notecnt -1 do
   retval, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote( take, i )
   if selected then
      
      if startppqpos >= note_pos then
         note_pos = startppqpos  
      end
   end
 end   
 
 for i = 0, notecnt -1 do
   retval, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote( take, i )
   if selected and startppqpos == note_pos then
      reaper.MIDI_SetNote( take, i  , false, muted, startppqpos, endppqpos, chan, pitch, vel, true )  
      
   end
 end

    reaper.MIDIEditor_OnCommand(ME,40405);--Set note ends to start of next note (legato)

    local t = {};
    local tSel = {};
    for i = 1,({reaper.MIDI_CountEvts(take)})[2] do;
        local retval,selected,muted,startppqpos,endppqpos,chan,pitch,vel = reaper.MIDI_GetNote(take,i-1);
        ---
        tSel[i-1] = selected;
        ---
    end;
    

    for i = 0, #tSel do;
        if tSel[i] == true then;
            local retval,selected,muted,startppqpos,endppqpos,chan,pitch,vel = reaper.MIDI_GetNote(take,i);
            reaper.MIDI_SetNote(take,i,tSel[i],muted,startppqpos,endppqpos+20,chan,pitch,vel,true);
        end;
    end;

time_start = reaper.time_precise()

local function Main()

    local elapsed = reaper.time_precise() - time_start  --set slowdown timer
    if elapsed >= 0.2 then  --pause 200ms

if correct then 
   reaper.MIDIEditor_LastFocused_OnCommand(40681,0) --Options: Correct overlapping notes while editing
end

        return
    else
        reaper.defer(Main)
    end
    
end

Main()
    reaper.MIDI_Sort(take);
    reaper.MIDIEditor_OnCommand(ME,reaper.NamedCommandLookup("_BR_ME_RESTORE_NOTE_SEL_SLOT_1"));--Restore note selection
    reaper.PreventUIRefresh(-1);
    reaper.Undo_EndBlock("Overlap Notes (legato)",-1);

Last edited by cool; 01-31-2020 at 01:05 AM.
cool is online now   Reply With Quote
Old 02-01-2020, 01:03 AM   #1966
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 205
Default

Hi guys! Me again

This time I tried to convert the EEL script to Lua and ran into one problem - the script works fine for two notes, but if there are more, it only processes the first two ones. As I understand it, here you need something like "repeat" and "until" commands, but this is already higher than my scripting abilities. Also, working with "while" commands is a pain, because each incorrect command leads to Reaper crashes.
By the way, is there any way in this script to avoid the "while" command using "for", for example?

The script from this topic: https://forum.cockos.com/showpost.ph...52&postcount=7
This is a script that joining adjacent and overlapping notes.

My code:

Code:
function join_adjacent_and_overlapping_notes()

take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive())

i = -1
i = reaper.MIDI_EnumSelNotes(take, i)
while i ~= -1 do
  retval, sel, muted, startppq, endppq, chan, pitch, vel = reaper.MIDI_GetNote(take, i)
      index_inner = i
        while index_inner ~= -1 do
        index_inner = reaper.MIDI_EnumSelNotes(take, index_inner)
            retval, _, _, startppqpos_next, endppqpos_next, chan_next, pitch_next = reaper.MIDI_GetNote( take, index_inner)

                 if chan == chan_next and pitch == pitch_next and endppq >= startppqpos_next then
                     reaper.MIDI_SetNote(take, i, selected, muted, startppq, endppqpos_next, chan, pitch, vel, true)  
                     reaper.MIDI_DeleteNote(take, index_inner)
                 end
           i = -1
        end
end

end

join_adjacent_and_overlapping_notes();
EEL Reference:


Code:
// Join adjacent and overlapping notes by spk77 15.8.2014)

function join_adjacent_and_overlapping_notes()
(
  (take = MIDIEditor_GetTake(MIDIEditor_GetActive())) ? (
    //UpdateItemInProject(GetMediaItemTake_Item(take));
    Undo_BeginBlock();
    //MIDIEditor_OnCommand(MIDIEditor_GetActive(), 40659); // Correct overlapping notes
    index = -1;
    while((index = MIDI_EnumSelNotes(take, index)) != -1) (
      MIDI_GetNote(take, index, is_selected, is_muted, start_pos, end_pos, chan, pitch, vol);
      index_inner = index;
      while((index_inner = MIDI_EnumSelNotes(take, index_inner)) != -1) (
        MIDI_GetNote(take, index_inner, 0, 0, start_pos_next, end_pos_next, chan_next, pitch_next, 0);
        chan == chan_next && pitch == pitch_next && end_pos >= start_pos_next  ? (
          MIDI_SetNote(take, index, is_selected, is_muted, start_pos, end_pos_next, chan, pitch, vol);
          index = -1;
          MIDI_DeleteNote(take, index_inner);
        );
      );
    );
    Undo_EndBlock("Join adjacent and overlapping notes", -1);
    //Undo_OnStateChange("Join adjacent and overlapping notes");
  );
);

join_adjacent_and_overlapping_notes();
cool is online now   Reply With Quote
Old 02-02-2020, 12:57 PM   #1967
_Stevie_
Human being with feelings
 
_Stevie_'s Avatar
 
Join Date: Oct 2017
Posts: 3,315
Default

Is the script only supposed to work for selected notes?

EDIT:

I adjusted the script a bit. On selection, this script will only join the selected notes,
if there's a selection, all notes will be joined.

Code:
function join_adjacent_and_overlapping_notes()

	if reaper.GetToggleCommandStateEx(32060, 40681) == 0 then -- if autocorrect overlapping notes is off
		reaper.MIDIEditor_OnCommand(reaper.MIDIEditor_GetActive(), 40659, 0) -- correct overlapping notes
	end

	
	local take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive())
	reaper.MIDI_DisableSort(take)
	if reaper.MIDI_EnumSelNotes(take, -1) ~= -1 then notes_selected = true end -- check, if there are selected notes, set notes_selected to true

	local _, num_notes, _, _ = reaper.MIDI_CountEvts(take)

	for n = 0, num_notes-1 do

		local retval, sel, muted, startppq, endppq, chan, pitch, vel = reaper.MIDI_GetNote(take, n)

		for m = 0, num_notes-1 do
		
			local retval, sel_next, _, startppqpos_next, endppqpos_next, chan_next, pitch_next = reaper.MIDI_GetNote( take, m)

			if chan == chan_next and pitch == pitch_next and endppq == startppqpos_next 
			and sel == sel_next
			and (sel or not notes_selected) then
				reaper.MIDI_SetNote(take, n, nil, nil, nil, endppqpos_next, nil, nil, nil, nil)  
				reaper.MIDI_DeleteNote(take, m)
			end
		end
	end

	reaper.MIDI_Sort(take)
end


join_adjacent_and_overlapping_notes()

As a sidenote: actually I would always use an array when deleting notes, because removing notes will always result in a chaos, when iterating from 0 to number of notes.
But for the sake of easier code, I went for the less complex solution.
__________________
My Reascripts forum thread | My Reascripts on GitHub | Stephan Römer - film composer
If you wish to donate for my scripts: please consider an organization like: animal shelter, doctors without borders, UNICEF, etc...

Last edited by _Stevie_; 02-02-2020 at 02:13 PM.
_Stevie_ is offline   Reply With Quote
Old 02-02-2020, 03:41 PM   #1968
FatSynth
Human being with feelings
 
Join Date: Jan 2020
Posts: 6
Default

Hi all!

I´m able to assign analog pots to control the multiple sends volumes of a track, but
i am dreaming if it´s possible with rotary encoders?

Example: Use of 2 encoders: One for select the row of the send and another to adjust their volume?

Thanks!!!
FatSynth is offline   Reply With Quote
Old 02-02-2020, 06:41 PM   #1969
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 205
Default

Quote:
Originally Posted by _Stevie_ View Post
Is the script only supposed to work for selected notes?
Yes, only selected. But I can tweak your code, it’s not difficult.

Overall - great job! I see you were able to get rid of "while" and it's cool! Thank you!

Ah, i found a bug.
The code still does not affect all notes: if there are several adjacent notes (3, 4 or more) in a row, then every second adjunction is skipped. It turns out that the problem is only half solved

P.S. finally, i fixed this! If you use other counter style ("for n = num_notes-1, 0, -1 do" and same for m), script working correct.


Yes, and even the script does not work without correction of the overlapped notes, I tried different options, but every time if the notes are overlapped, they are deleted. In this regard, the original EEL script looks perfect - it is simple and works flawlessly in any work scenarios. Ingenious code.

Last edited by cool; 02-02-2020 at 07:33 PM.
cool is online now   Reply With Quote
Old 02-18-2020, 09:39 AM   #1970
Triode
Human being with feelings
 
Triode's Avatar
 
Join Date: Jan 2012
Posts: 588
Default

Quote:
Originally Posted by cool View Post
Ha! It's hard to believe, but I think I completely solved my problem! At least the first tests were excellent!

I combined several solutions - a successful "remove" action and additional commands to solve their requests. Perhaps this does not look correct from the programmer's point of view, but .... it works!
The script has one drawback. With any selection of the area, the automation items are not deleted. But this is a trifle, in my workflow I can ignore it without much trouble.

FnA, James HE, guys, thank you very much for your help! This is priceless for me!

Final code:

Code:
start, ending = reaper.GetSet_LoopTimeRange( 0, 0, 0, 0, 0 )
--focus = reaper.GetCursorContext()
focus = reaper.GetCursorContext2(true) -- unlikely to get unknown(-1) when arrange not focused


  script_title = "Smart Delete Script" 
  reaper.Undo_BeginBlock() 

if start == ending then
  reaper.Main_OnCommand(40697, 0) -- remove items/tracks/...
else
  if focus == 1 then
    reaper.Main_OnCommand(40061, 0) -- split items at time selection
    reaper.Main_OnCommand(40697, 0) -- remove selected area of items
  elseif focus == 2 then
    reaper.Main_OnCommand(40333, 0)  --  delete selected points
  else -- alternatively -- elseif focus == 0 then
    reaper.Main_OnCommand(40697, 0) -- remove tracks
  end
end

  reaper.Undo_EndBlock(script_title, 0)
It would be good if this script could detect whether an fx chain is in focus and then delete the selected fx. I've tried messing with reaper.CF_GetFocusedFXChain() to no avail so far..
__________________
Brush and Beater Drums Online: www.outoftheboxdrums.co.uk
Triode is offline   Reply With Quote
Old 02-18-2020, 11:00 AM   #1971
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 1,634
Default

Quote:
Originally Posted by Triode View Post
It would be good if this script could detect whether an fx chain is in focus and then delete the selected fx. I've tried messing with reaper.CF_GetFocusedFXChain() to no avail so far..
CF_GetFocusedFXChain has a few bugs, hopefully fixed in next SWS release.

Depending on what build/version of SWS you're using you may see,..
Returns nil if track has a name.
Returns nil if track is a folder.
May return wrong handle with multiple projects and the Hide background FX option is disabled.

EDIT Actually I was thinking of CF_GetTrackFXChain function, unsure if CF_GetFocusedFXChain has same problems.

Last edited by Edgemeal; 02-18-2020 at 11:39 AM.
Edgemeal is offline   Reply With Quote
Old 02-18-2020, 11:08 AM   #1972
Triode
Human being with feelings
 
Triode's Avatar
 
Join Date: Jan 2012
Posts: 588
Default

Ok thanks. It's not just my dubious scripting then
__________________
Brush and Beater Drums Online: www.outoftheboxdrums.co.uk
Triode is offline   Reply With Quote
Old 02-18-2020, 11:38 AM   #1973
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 1,634
Default

Quote:
Originally Posted by Triode View Post
Ok thanks. It's not just my dubious scripting then
Actually I was thinking of the CF_GetTrackFXChain function, not sure if CF_GetFocusedFXChain has any of these same problems.
Edgemeal is offline   Reply With Quote
Old 02-18-2020, 11:51 AM   #1974
Triode
Human being with feelings
 
Triode's Avatar
 
Join Date: Jan 2012
Posts: 588
Default

In fact I've almost got this working (via JS API)
It's just sometimes not deleting tracks when on the mixer window
Can you see why? I'm stumped - most likely by something basic..

Code:
start, ending = reaper.GetSet_LoopTimeRange( 0, 0, 0, 0, 0 )
--focus = reaper.GetCursorContext()
focus = reaper.GetCursorContext2(true) -- unlikely to get unknown(-1) when arrange not focused
  local reaper = reaper
  local FX_win = reaper.JS_Window_Find("FX: ", false )

  script_title = "Smart Delete Script" 
  reaper.Undo_BeginBlock() 
  

    if FX_win then
      local title = reaper.JS_Window_GetTitle( FX_win, "" )
      if title:match("FX: Track ") then
      reaper.Main_OnCommand(reaper.NamedCommandLookup('_S&M_REMOVE_FX'),0)
      end
      end
      
      if not FX_win then

if start == ending then
  reaper.Main_OnCommand(40697, 0) -- remove items/tracks/...
elseif focus == 1 then
    reaper.Main_OnCommand(40061, 0) -- split items at time selection
    reaper.Main_OnCommand(40697, 0) -- remove selected area of items
  elseif focus == 2 then
    reaper.Main_OnCommand(40333, 0)  --  delete selected points
  
  else   -- alternatively -- elseif focus == 0 then
    reaper.Main_OnCommand(40697, 0) -- remove tracks
    
    
    end
  end
  

  
  reaper.Undo_EndBlock(script_title, 0)
__________________
Brush and Beater Drums Online: www.outoftheboxdrums.co.uk
Triode 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 09:05 PM.


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