Old 10-21-2020, 12:03 PM   #1
jguitarguy27
Human being with feelings
 
Join Date: Oct 2007
Posts: 135
Default Can someone help me with the loop for this script?

Hi all,

I'm new to Reascript and lua, and I'm hoping someone can help me connect the dots for what I have so far.

So I'm trying to make a script that looks at the selected items, and moves them to the next track if they're stereo. I made this little script that works for a single selected item:

=================================================
MediaItem = reaper.GetSelectedMediaItem( 0, 0 )
MediaItem_Take = reaper.GetActiveTake( MediaItem )
pcm_source = reaper.GetMediaItemTake_Source( MediaItem_Take )
ch = reaper.GetMediaSourceNumChannels( pcm_source )
MediaTrack = reaper.GetMediaItemTrack( MediaItem )

if ch == 2 then
reaper.Main_OnCommand(40118, 0)
end
=================================================

Now, I know that in order to make this work on a group of selected items, it needs to be encapsulated in some kind of "for" loop (I think). Could someone help me with the syntax of this?
jguitarguy27 is offline   Reply With Quote
Old 10-21-2020, 12:24 PM   #2
Ben Osterhouse
Human being with feelings
 
Join Date: Jan 2019
Posts: 50
Default

Here is one way you could do it:

Code:
num_selected_items = reaper.CountSelectedMediaItems(0)

selected_items = {}
for i = 0, num_selected_items - 1 do
	selected_items[i] = reaper.GetSelectedMediaItem( 0, i )
end
for i = 0, num_selected_items - 1 do
	reaper.SetMediaItemSelected(selected_items[i], false)
end

for i = 0, num_selected_items - 1 do
	MediaItem = selected_items[i]
	MediaItem_Take = reaper.GetActiveTake( MediaItem )
	pcm_source = reaper.GetMediaItemTake_Source( MediaItem_Take )
	ch = reaper.GetMediaSourceNumChannels( pcm_source )
	MediaTrack = reaper.GetMediaItemTrack( MediaItem )

	if ch == 2 then
		reaper.SetMediaItemSelected(MediaItem, true)
	end
end
reaper.Main_OnCommand(40118, 0)
reaper.UpdateArrange()
Ben Osterhouse is offline   Reply With Quote
Old 10-21-2020, 12:33 PM   #3
jguitarguy27
Human being with feelings
 
Join Date: Oct 2007
Posts: 135
Default

Wow that's great thank you. I'm going to study this and learn from it!
jguitarguy27 is offline   Reply With Quote
Old 10-21-2020, 12:45 PM   #4
Ben Osterhouse
Human being with feelings
 
Join Date: Jan 2019
Posts: 50
Default

No problem, yeah I was trying to do something similar to this recently and got really tripped up because I didn't realize you have to reaper.UpdateArrange(). Otherwise when you've selected or unselected items, the new selections won't actually show up until you click somewhere.
Ben Osterhouse is offline   Reply With Quote
Old 10-21-2020, 02:30 PM   #5
lexaproductions
Human being with feelings
 
Join Date: Jan 2013
Posts: 689
Default

If you want to do your search only on the currently selected items, you might wanna try to do it the other way around:

Loop through the selected items and for each item:
Look if it's stereo
If not then deselect it.
When you're done. move the remainder to the next track.
lexaproductions is online now   Reply With Quote
Old 10-21-2020, 02:35 PM   #6
Ben Osterhouse
Human being with feelings
 
Join Date: Jan 2019
Posts: 50
Default

O yeah that would be simpler, I didn't think of that.
Ben Osterhouse is offline   Reply With Quote
Old 10-22-2020, 12:16 PM   #7
Triode
Human being with feelings
 
Triode's Avatar
 
Join Date: Jan 2012
Posts: 832
Default

This is a good showcase of how to use an array for selected items and do stuff to them one at a time. This has always been a mystery to me!
__________________
Mixing / Brush and Beater Drums Online: www.outoftheboxsounds.com
Triode is online now   Reply With Quote
Old 10-22-2020, 01:14 PM   #8
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 2,361
Default

You wouldn't actually need an array for this, if the code is changing the selected state of the selected items then all you need to do is loop backwards, basically what lexaproductions said...

Code:
for i = reaper.CountSelectedMediaItems(0)-1, 0, -1 do -- loop backwards
  MediaItem = reaper.GetSelectedMediaItem( 0, i )
  MediaItem_Take = reaper.GetActiveTake( MediaItem )
  pcm_source = reaper.GetMediaItemTake_Source( MediaItem_Take )
  ch = reaper.GetMediaSourceNumChannels( pcm_source )
  if ch ~= 2 then reaper.SetMediaItemSelected(MediaItem, false) end
end
reaper.Main_OnCommand(40118, 0)
reaper.UpdateArrange()
Edgemeal is offline   Reply With Quote
Old 10-22-2020, 01:24 PM   #9
Ben Osterhouse
Human being with feelings
 
Join Date: Jan 2019
Posts: 50
Default

Hey there we go! Yeah because looping forward, the index would get messed up.
Ben Osterhouse is offline   Reply With Quote
Old 10-27-2020, 09:28 AM   #10
jguitarguy27
Human being with feelings
 
Join Date: Oct 2007
Posts: 135
Default

Hey guys, thanks for all your input on this. To practice and learn, I'm re-writing this from scratch (yeah, I know the answer has been posted, but I'll learn better if I can do it start-to-finish on my own)

I'm currently at the step of "deselect selected items if they have one channel". If you take this code and run it, it will successfully show in a console window the number of channels each selected item has. However, if I comment out the message blocks where the if statements are, and instead use "reaper.setmediaitemselected", I can't get it to properly set the selected state for each of the items. Where am I going wrong?


Code:
function Msg(param)
	reaper.ShowConsoleMsg(tostring(param).."\n")
end

function Main()

		count_sel_items = reaper.CountSelectedMediaItems(0) 

	for i = 0, count_sel_items - 1 do
		sel_item = reaper.GetSelectedMediaItem( 0, i ) 
		mediaitem_take = reaper.GetActiveTake( sel_item ) 
		pcm_source = reaper.GetMediaItemTake_Source( mediaitem_take )  
		ch = reaper.GetMediaSourceNumChannels( pcm_source ) 
	
		if ch == 2 then
		-- reaper.SetMediaItemSelected( sel_item, 1 )
			Msg("2ch")
		elseif ch == 1 then
		-- reaper.SetMediaItemSelected( sel_item, 0 )
			Msg("1ch")
		end
	
	end

end

Main()

reaper.UpdateArrange()

Last edited by jguitarguy27; 10-27-2020 at 09:39 AM.
jguitarguy27 is offline   Reply With Quote
Old 10-27-2020, 09:55 AM   #11
Ben Osterhouse
Human being with feelings
 
Join Date: Jan 2019
Posts: 50
Default

If it's deselected an item, then next time through the loop it will not count that item as a selected item when you do reaper.GetSelectedMediaItem( 0, i )
Ben Osterhouse is offline   Reply With Quote
Old 10-27-2020, 10:01 AM   #12
jkooks
Human being with feelings
 
Join Date: May 2020
Posts: 175
Default

Quote:
Originally Posted by jguitarguy27 View Post
Hey guys, thanks for all your input on this. To practice and learn, I'm re-writing this from scratch (yeah, I know the answer has been posted, but I'll learn better if I can do it start-to-finish on my own)

I'm currently at the step of "deselect selected items if they have one channel". If you take this code and run it, it will successfully show in a console window the number of channels each selected item has. However, if I comment out the message blocks where the if statements are, and instead use "reaper.setmediaitemselected", I can't get it to properly set the selected state for each of the items. Where am I going wrong?


Code:
function Msg(param)
	reaper.ShowConsoleMsg(tostring(param).."\n")
end

function Main()

		count_sel_items = reaper.CountSelectedMediaItems(0) 

	for i = 0, count_sel_items - 1 do
		sel_item = reaper.GetSelectedMediaItem( 0, i ) 
		mediaitem_take = reaper.GetActiveTake( sel_item ) 
		pcm_source = reaper.GetMediaItemTake_Source( mediaitem_take )  
		ch = reaper.GetMediaSourceNumChannels( pcm_source ) 
	
		if ch == 2 then
		-- reaper.SetMediaItemSelected( sel_item, 1 )
			Msg("2ch")
		elseif ch == 1 then
		-- reaper.SetMediaItemSelected( sel_item, 0 )
			Msg("1ch")
		end
	
	end

end

Main()

reaper.UpdateArrange()


The reason it isn't working as expected is because you are unselecting items that were previously selected, changing the selected item count and therefore messing up the items that are returned by GetMediaItemSelected. This will cause some items to be skipped, as what used to be item 1 in the index now becomes item 0 if the one before it gets unselected.

In order to fix this you just need to iterate backwards, which means you need to change your for loop statement from this:

Code:
for i = 0, count_sel_items - 1 do
to this:

Code:
for i = count_sel_items - 1, 0, -1 do

This change tells Lua to start the index at count_sel_items - 1 and to go until it hits 0, decreasing the index by 1 every iteration.
jkooks is offline   Reply With Quote
Old 10-27-2020, 12:30 PM   #13
jguitarguy27
Human being with feelings
 
Join Date: Oct 2007
Posts: 135
Default

Quote:
Originally Posted by jkooks View Post
The reason it isn't working as expected is because you are unselecting items that were previously selected, changing the selected item count and therefore messing up the items that are returned by GetMediaItemSelected. This will cause some items to be skipped, as what used to be item 1 in the index now becomes item 0 if the one before it gets unselected.

In order to fix this you just need to iterate backwards, which means you need to change your for loop statement from this:

Code:
for i = 0, count_sel_items - 1 do
to this:

Code:
for i = count_sel_items - 1, 0, -1 do

This change tells Lua to start the index at count_sel_items - 1 and to go until it hits 0, decreasing the index by 1 every iteration.
Ahhh I see...by virtue of altering if they are selected/unselected, it's kind of screwing the loop up. Thanks!
jguitarguy27 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 11:28 AM.


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