Old 05-11-2020, 02:42 AM   #1
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default Random Item Length

Hi
Search for a script.
"Randomize the length of the selected items depending on the set grid"
Preferred value 1/16 grid.

If the total length of the selected items after the execution of the script exceeds or falls below the initial value, it would not matter.
If not, it would be better.

multi = {1,2,3,4,5,6,7,8}

grid_multi = multi[math.random(1,#multi)]

new_length = grid_length * grid_multi

new_rate = old_playrate*(old_length/new_length)

Maybe someone can help me there.
I hope I have expressed myself correctly.
Thanks

Last edited by Dragonetti; 06-18-2020 at 02:35 PM.
Dragonetti is offline   Reply With Quote
Old 05-11-2020, 11:44 AM   #2
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

Now I just have to hang the items one after the other.
The 1st item is in place.
Can someone help?
Thanks

Code:
ItemsSel = {}

ItemsSelCount = reaper.CountSelectedMediaItems(0)
for i = 0, ItemsSelCount - 1 do 

item = reaper.GetSelectedMediaItem(0, i)  
take = reaper.GetActiveTake(item) 
  
Idx = i + 1 -- 1-based table in Lua   
ItemsSel[Idx] = {}
ItemsSel[Idx].position =  reaper.GetMediaItemInfo_Value( item, "D_POSITION" )
ItemsSel[Idx].playrate = reaper.GetMediaItemTakeInfo_Value(take, "D_PLAYRATE")
ItemsSel[Idx].length = reaper.GetMediaItemInfo_Value( item, "D_LENGTH")


start = ItemsSel[1].position  
grid_end = reaper.BR_GetNextGridDivision( start) 
grid_length = grid_end - start


Grids = {"1","2","3","4","5","6","7","8"} --multipliers to create a new length
Rand = Grids[math.random(1,#Grids)]      
number = tonumber(Rand)

old_length = ItemsSel[Idx].length
playrate = ItemsSel[Idx].playrate
new_length = number * grid_length  --new length randomly created from the table values x grid_length
new_rate = ItemsSel[Idx].playrate*(old_length/new_length)

--new_position = ItemsSel[1].position


reaper.SetMediaItemInfo_Value(item, "D_LENGTH",new_length)
reaper.SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", new_rate)
--reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position)

end

reaper.UpdateArrange()

Last edited by Dragonetti; 05-11-2020 at 12:42 PM.
Dragonetti is offline   Reply With Quote
Old 05-11-2020, 12:26 PM   #3
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

You really should write comments in your code of what the individual parts are supposed to do.

And you should simply write more, what the script is supposed to do as well.
"Randomize the length of the selected items depending on the set grid" is more like the title of the description, not the description itself, which is much longer.You should also answer the usual questions of why, what, how, where and what for.

The gif isn't really helpful as well. I only see you dragging items and changing their length, but I don't see the randomization coming into play. So what are we supposed to see in there?
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-11-2020, 01:01 PM   #4
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

@Meo-Ada Mespotine
The script is supposed to randomly create a rhythmic change in a melody.
It is crucial that the result (start and end of items)is exactly on the grid.
The new lengths of the selected items should be a multiple of the grid length.

!!!This function is still missing in the code:
all gaps and overlaps have to be removed.(move items to each other)
like in the first gif
I can't really do it
Thanks




Dragonetti is offline   Reply With Quote
Old 05-11-2020, 01:53 PM   #5
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

In case you are using my Ultraschall-API as well, this function could help you getting the gaps inbetween items:

https://mespotin.uber.space/Ultrasch...psBetweenItems
With that, you only need to move the items "forwards" towards the beginning of the project.

It's only the selected items in question and only in one track?
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-11-2020, 02:00 PM   #6
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

Yes only the selected ones on only one track.
If there are overlaps, what can I do?
Dragonetti is offline   Reply With Quote
Old 05-11-2020, 02:04 PM   #7
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

These are actually the biggest difficulty. Especially if one overlapping item begins and ends after another one, so the second item is "submerged" underneath the first one.

What would you prefer? How should it be done, if you could code it?
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-11-2020, 02:36 PM   #8
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

The original order must be preserved. item1 item2 item3 item4 ....
item1 stays in the same position
position item2 becomes old position [1] + new length [1]
position item3 becomes new position [2] + new length [2]
position item4 becomes new position [3] + new length [3]
etc

Last edited by Dragonetti; 05-11-2020 at 03:28 PM.
Dragonetti is offline   Reply With Quote
Old 05-12-2020, 03:20 AM   #9
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

After changing the length, I want to read in all items again. It does not work.
I marked the place of the new reading in the code.

Code:
--local function Msg(str)
 -- reaper.ShowConsoleMsg(tostring(str) .. "\n")
--end

ItemsSel = {}

ItemsSelCount = reaper.CountSelectedMediaItems(0)
for i = 0, ItemsSelCount - 1 do 

item = reaper.GetSelectedMediaItem(0, i)  
take = reaper.GetActiveTake(item) 
  
Idx = i + 1 -- 1-based table in Lua   
ItemsSel[Idx] = {}
ItemsSel[Idx].position =  reaper.GetMediaItemInfo_Value( item, "D_POSITION" )
ItemsSel[Idx].playrate = reaper.GetMediaItemTakeInfo_Value(take, "D_PLAYRATE")
ItemsSel[Idx].length = reaper.GetMediaItemInfo_Value( item, "D_LENGTH")


start = ItemsSel[1].position  
grid_end = reaper.BR_GetNextGridDivision( start) 
grid_length = grid_end - start


Grids = {"0.5","1.5"}  
Rand = Grids[math.random(1,#Grids)]   
number = tonumber(Rand)

old_length = ItemsSel[Idx].length
playrate = ItemsSel[Idx].playrate
new_length = number * grid_length --new length randomly created from the table values x grid_length
new_rate = ItemsSel[Idx].playrate*(old_length/new_length)




reaper.SetMediaItemInfo_Value(item, "D_LENGTH",new_length)
reaper.SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", new_rate)
--reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position)

end
--------------------------------------------------------------------------------------------------
---------new reading of the changed items ----------------------------------------
--------------------------------------------------------------------------------------------------
ItemsSel1 = {}

ItemsSelCount1 = reaper.CountSelectedMediaItems(0)
for a = 0, ItemsSelCount1 - 1 do 

item1 = reaper.GetSelectedMediaItem(0, a)  
take1 = reaper.GetActiveTake(item1) 
  
Idx1 = a + 1 -- 1-based table in Lua   
ItemsSel1[Idx1] = {}
ItemsSel1[Idx1].position1 =  reaper.GetMediaItemInfo_Value( item1, "D_POSITION" )
ItemsSel1[Idx1].playrate1 = reaper.GetMediaItemTakeInfo_Value(take1, "D_PLAYRATE")
ItemsSel1[Idx1].length1 = reaper.GetMediaItemInfo_Value( item1, "D_LENGTH")
ItemsSel1[Idx1].position1 = position_New
ItemsSel1[Idx1].length1 = length_New
end

--for i = 1, 
--reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position) do
--new_position = ItemsSel1[1].position else
--new_position = position_New + length_new


--reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position)
--end--]],

reaper.UpdateArrange()   
 
--Msg(old_length)
Dragonetti is offline   Reply With Quote
Old 05-15-2020, 10:32 AM   #10
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

Hi
The items all remain in position.
How do I get them pushed together?
Do I have to do this with main loop?
Thanks




Code:
--------------- RANDOM_LENGTH(multi Grid)----------------


ItemsSel = {}

ItemsSelCount = reaper.CountSelectedMediaItems(0)
for i = 0, ItemsSelCount - 1 do 

item = reaper.GetSelectedMediaItem(0, i)  
take = reaper.GetActiveTake(item) 
  
Idx = i + 1 -- 1-based table in Lua    
ItemsSel[Idx] = {}
ItemsSel[Idx].position =  reaper.GetMediaItemInfo_Value( item, "D_POSITION" )
ItemsSel[Idx].playrate = reaper.GetMediaItemTakeInfo_Value(take, "D_PLAYRATE")
ItemsSel[Idx].length = reaper.GetMediaItemInfo_Value( item, "D_LENGTH")


start = ItemsSel[1].position  
grid_end = reaper.BR_GetNextGridDivision( start)    
grid_length = grid_end - start
  
  
Grids = {"1.5","1","2","3","4",}    
Rand = Grids[math.random(1,#Grids)]   
number = tonumber(Rand) 

old_length = ItemsSel[Idx].length
playrate = ItemsSel[Idx].playrate
new_length = number * grid_length --new length randomly created from the table values x grid_length
new_rate = ItemsSel[Idx].playrate*(old_length/new_length)




reaper.SetMediaItemInfo_Value(item, "D_LENGTH",new_length)
reaper.SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", new_rate)
--reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position)

end
--------------------------------------------------------------------------------------------------
---------new reading of the changed items ----------------------------------------
--------------------------------------------------------------------------------------------------
--[[ItemsSel1 = {}

ItemsSelCount1 = reaper.CountSelectedMediaItems(0)
for a = 0, ItemsSelCount1 - 1 do 

item1 = reaper.GetSelectedMediaItem(0, a)   
take1 = reaper.GetActiveTake(item1) 
   
Idx1 = a + 1 -- 1-based table in Lua   
ItemsSel1[Idx1] = {}
ItemsSel1[Idx1].position1 =  reaper.GetMediaItemInfo_Value( item1, "D_POSITION" )
ItemsSel1[Idx1].playrate1 = reaper.GetMediaItemTakeInfo_Value(take1, "D_PLAYRATE")
ItemsSel1[Idx1].length1 = reaper.GetMediaItemInfo_Value( item1, "D_LENGTH")
ItemsSel1[Idx1].position1 = position_New
ItemsSel1[Idx1].length1 = length_New
end

--for i = 1, 
--reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position) do
--new_position = ItemsSel1[1].position else
--new_position = position_New + length_new


--reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position)
--end--]]

reaper.UpdateArrange()
Dragonetti is offline   Reply With Quote
Old 05-15-2020, 01:30 PM   #11
jkuk
Human being with feelings
 
Join Date: Feb 2019
Posts: 17
Default

I think the easiest way for to have all the newly changed items "snap" to the previous one would be to run through them after changing all of their lengths. Something along the lines of this should work:

Code:
for i = 1, ItemsSelCount - 1 do

	--grabs items
	prevItem = reaper.GetSelectedMediaItem(0, i-1)
	thisItem = reaper.GetSelectedMediaItem(0, i)

	--grabs previous item's info
	prevStart = reaper.GetMediaItemInfo_Value(prevItem, "D_POSITION")
	prevLen = reaper.GetMediaItemInfo_Value(prevItem, "D_LENGTH")
	prevEnd = prevStart + prevLen

	reaper.SetMediaItemInfo_Value(thisItem, "D_POSITION", prevEnd) --sets item to be at the end of the previous item

end

Last edited by jkuk; 05-15-2020 at 01:32 PM. Reason: Makes it prettier with code window
jkuk is offline   Reply With Quote
Old 05-15-2020, 02:49 PM   #12
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

Thanks a lot
But ,the order of the items changed after a few runs.
Above all with slightly higher multi grid values (4, 5 ..).
Is it possible to keep the original order.
Thanks
Dragonetti is offline   Reply With Quote
Old 05-15-2020, 07:40 PM   #13
jkuk
Human being with feelings
 
Join Date: Feb 2019
Posts: 17
Default

Alright, I adjusted the way the second for loop worked and added another the items to your table in order to keep the original order. The issue arose whenever an item was being lengthened into another item, but this should work regardless of whether or not that happens.

Code:
ItemsSel = {}

ItemsSelCount = reaper.CountSelectedMediaItems(0)
for i = 0, ItemsSelCount - 1 do 

	item = reaper.GetSelectedMediaItem(0, i)  
	take = reaper.GetActiveTake(item) 
	  
	Idx = i + 1 -- 1-based table in Lua    
	ItemsSel[Idx] = {}
	ItemsSel[Idx].thisItem = item
	ItemsSel[Idx].position =  reaper.GetMediaItemInfo_Value( item, "D_POSITION" )
	ItemsSel[Idx].playrate = reaper.GetMediaItemTakeInfo_Value(take, "D_PLAYRATE")
	ItemsSel[Idx].length = reaper.GetMediaItemInfo_Value( item, "D_LENGTH")


	start = ItemsSel[1].position  
	grid_end = reaper.BR_GetNextGridDivision( start)    
	grid_length = grid_end - start
	  
	  
	Grids = {"1.5","1","2","3","4",}    
	Rand = Grids[math.random(1,#Grids)]  
	number = tonumber(Rand) 
	-- reaper.ShowConsoleMsg(i .. "\nRand = " .. Rand .. "\n" .. "Number = " .. number .. "\n\n")

	old_length = ItemsSel[Idx].length
	playrate = ItemsSel[Idx].playrate
	new_length = number * grid_length --new length randomly created from the table values x grid_length
	new_rate = ItemsSel[Idx].playrate*(old_length/new_length)




	reaper.SetMediaItemInfo_Value(item, "D_LENGTH",new_length)
	reaper.SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", new_rate)
	--reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position)

end

for i = 1, ItemsSelCount-1 do

	--grabs items
	prevItem = ItemsSel[i].thisItem
	thisItem = ItemsSel[i+1].thisItem

	--grabs previous item's info
	prevStart = reaper.GetMediaItemInfo_Value(prevItem, "D_POSITION")
	prevLen = reaper.GetMediaItemInfo_Value(prevItem, "D_LENGTH")
	prevEnd = prevStart + prevLen

	reaper.SetMediaItemInfo_Value(thisItem, "D_POSITION", prevEnd) --sets item to be at the end of the previous item
end
jkuk is offline   Reply With Quote
Old 05-16-2020, 02:32 AM   #14
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

It works great.
Thanks a lot.
I'll take a closer look at the code to learn from it.
Dragonetti is offline   Reply With Quote
Old 06-18-2020, 07:24 AM   #15
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

Can someone install that.
The script should be run 20 times, then it should stop.
However, if the last selected item has the same end point (position + length) as the time selection, it should stop.
Thank you

Code:
------- random item length grid dependent -------
----- script by  jkuk and dragonetti -------
---https://forum.cockos.com/showthread.php?p=2285825#post2285825

ItemsSel = {}

ItemsSelCount = reaper.CountSelectedMediaItems(0)
for i = 0, ItemsSelCount - 1 do      
  item = reaper.GetSelectedMediaItem(0, i)  
  take = reaper.GetActiveTake(item) 
    
  Idx = i + 1 -- 1-based table in Lua    
  ItemsSel[Idx] = {} 
  ItemsSel[Idx].thisItem = item
  ItemsSel[Idx].position =  reaper.GetMediaItemInfo_Value( item, "D_POSITION" )
  ItemsSel[Idx].playrate = reaper.GetMediaItemTakeInfo_Value(take, "D_PLAYRATE")
  ItemsSel[Idx].length = reaper.GetMediaItemInfo_Value( item, "D_LENGTH")


  start = ItemsSel[1].position  
  grid_end = reaper.BR_GetNextGridDivision( start)    
  grid_length = grid_end - start
    
    
  Grids = {"1","2","3","4"}
  Rand = Grids[math.random(1,#Grids)]  
  number = tonumber(Rand) 
  -- reaper.ShowConsoleMsg(i .. "\nRand = " .. Rand .. "\n" .. "Number = " .. number .. "\n\n")

  old_length = ItemsSel[Idx].length
  playrate = ItemsSel[Idx].playrate
  new_length = number * grid_length --new length randomly created from the table values x grid_length
  new_rate = ItemsSel[Idx].playrate*(old_length/new_length)




  reaper.SetMediaItemInfo_Value(item, "D_LENGTH",new_length)
  reaper.SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", new_rate)
  --reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position)

end 
 
for i = 1, ItemsSelCount-1 do

  --grabs items
  prevItem = ItemsSel[i].thisItem
  thisItem = ItemsSel[i+1].thisItem

  --grabs previous item's info
  prevStart = reaper.GetMediaItemInfo_Value(prevItem, "D_POSITION")
  prevLen = reaper.GetMediaItemInfo_Value(prevItem, "D_LENGTH")
  prevEnd = prevStart + prevLen

  reaper.SetMediaItemInfo_Value(thisItem, "D_POSITION", prevEnd) --sets item to be at the end of the previous item
end
Dragonetti is offline   Reply With Quote
Old 06-20-2020, 08:51 AM   #16
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

success stories
I didn't think I could do it
thanks solger

Code:
--- random_length within the time selection depending on grid----
----- script by  jkuk,dragonetti and solger -------
---https://forum.cockos.com/showthread.php?p=2285825#post2285825

for a=1,100 do
------------------------------------------------   
ItemsSel = {}
 
loop_start, loop_end = reaper.GetSet_LoopTimeRange(false,true,0,0,false  )

ItemsSelCount = reaper.CountSelectedMediaItems(0)
for i = 0, ItemsSelCount - 1 do      
  item = reaper.GetSelectedMediaItem(0, i)   
  take = reaper.GetActiveTake(item) 
    
  Idx = i + 1 -- 1-based table in Lua    
  ItemsSel[Idx] = {} 
  ItemsSel[Idx].thisItem = item
  ItemsSel[Idx].position =  reaper.GetMediaItemInfo_Value( item, "D_POSITION" )
  ItemsSel[Idx].playrate = reaper.GetMediaItemTakeInfo_Value(take, "D_PLAYRATE")
  ItemsSel[Idx].length = reaper.GetMediaItemInfo_Value( item, "D_LENGTH")
  

  
  start = ItemsSel[1].position  
  grid_end = reaper.BR_GetNextGridDivision( start)      
  grid_length = grid_end - start
    
    
  Grids = {"1","2","3","4"}
  Rand = Grids[math.random(1,#Grids)]  
  number = tonumber(Rand) 
 

  old_length = ItemsSel[Idx].length
  playrate = ItemsSel[Idx].playrate
  new_length = number * grid_length --new length randomly created from the table values x grid_length
  new_rate = ItemsSel[Idx].playrate*(old_length/new_length)




  reaper.SetMediaItemInfo_Value(item, "D_LENGTH",new_length)
  reaper.SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", new_rate)
  --reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position)
--ItemsSel[ItemsSelCount - 1].position  = last_pos
end 
 
for i = 1, ItemsSelCount-1 do

  --grabs items
  prevItem = ItemsSel[i].thisItem
  thisItem = ItemsSel[i+1].thisItem

  --grabs previous item's info
  prevStart = reaper.GetMediaItemInfo_Value(prevItem, "D_POSITION")
  prevLen = reaper.GetMediaItemInfo_Value(prevItem, "D_LENGTH")
  prevEnd = prevStart + prevLen

  reaper.SetMediaItemInfo_Value(thisItem, "D_POSITION", prevEnd) --sets item to be at the end of the previous item
  
  item = reaper.GetSelectedMediaItem(0, ItemsSelCount - 1)  
  last_item = reaper.GetMediaItemInfo_Value( item, "D_POSITION" )
  last_item_length = reaper.GetMediaItemInfo_Value( item, "D_LENGTH" )
  endposi = last_item + last_item_length
end


  if endposi == loop_end then break end
end

Last edited by Dragonetti; 06-20-2020 at 08:59 AM.
Dragonetti is offline   Reply With Quote
Old 08-06-2020, 01:17 PM   #17
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

The whole works well for one track.
This does not work for several selected items on different tracks.
The script should transfer the same values from the first track to the other tracks.
Can someone help me there.
Thank you
The code is in post # 16

Last edited by Dragonetti; 08-06-2020 at 01:36 PM.
Dragonetti is offline   Reply With Quote
Old 08-07-2020, 08:25 PM   #18
jkooks
Human being with feelings
 
Join Date: May 2020
Posts: 190
Default

Something along these lines should work, as long as the same amount of items are on each track.

Code:
--- random_length within the time selection depending on grid----
----- script by  jkuk,dragonetti and solger -------
---https://forum.cockos.com/showthread.php?p=2285825#post2285825

------------------------------------------------   
reaper.Undo_BeginBlock()
reaper.PreventUIRefresh(1)

ItemsSel = {}
Idx = 1

otherItems = {} 
counter = 1

loop_start, loop_end = reaper.GetSet_LoopTimeRange(false,true,0,0,false  )

mainTrack = reaper.GetMediaItem_Track(reaper.GetSelectedMediaItem(0, 0))

ItemsSelCount = reaper.CountSelectedMediaItems(0)
for i = 0, ItemsSelCount - 1 do
  item = reaper.GetSelectedMediaItem(0, i)
  take = reaper.GetActiveTake(item) 

  local thisTrack = reaper.GetMediaItem_Track(item)

  if thisTrack == mainTrack then
       
    ItemsSel[Idx] = {} 
    ItemsSel[Idx].thisItem = item
    ItemsSel[Idx].oldPosition =  reaper.GetMediaItemInfo_Value( item, "D_POSITION" )
    ItemsSel[Idx].oldPlayrate = reaper.GetMediaItemTakeInfo_Value(take, "D_PLAYRATE")
    ItemsSel[Idx].oldLength = reaper.GetMediaItemInfo_Value( item, "D_LENGTH")
    
    start = ItemsSel[1].oldPosition  
    grid_end = reaper.BR_GetNextGridDivision( start)      
    grid_length = grid_end - start
      
      
    Grids = {"1","2","3","4"}
    Rand = Grids[math.random(1,#Grids)]  
    number = tonumber(Rand) 
   

    old_length = ItemsSel[Idx].oldLength
    playrate = ItemsSel[Idx].oldPlayrate
    new_length = number * grid_length --new length randomly created from the table values x grid_length
    new_rate = ItemsSel[Idx].oldPlayrate*(old_length/new_length)


    ItemsSel[Idx].newLength = new_length
    ItemsSel[Idx].newRate = new_rate


    reaper.SetMediaItemInfo_Value(item, "D_LENGTH",new_length)
    reaper.SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", new_rate)

    Idx = Idx + 1 -- 1-based table in Lua 

  else
    otherItems[counter] = {
      item = item,
      take = take,
      track = thisTrack,
    }

    counter = counter + 1
  end
end
 
for i = 2, Idx - 1 do

  --grabs items
  local prevItem = ItemsSel[i-1].thisItem
  local thisItem = ItemsSel[i].thisItem

  --grabs previous item's info
  local prevStart = reaper.GetMediaItemInfo_Value(prevItem, "D_POSITION")
  local prevLen = reaper.GetMediaItemInfo_Value(prevItem, "D_LENGTH")
  local prevEnd = prevStart + prevLen


  ItemsSel[i].newStart = prevEnd


  reaper.SetMediaItemInfo_Value(thisItem, "D_POSITION", prevEnd) --sets item to be at the end of the previous item
end

local index = 1
for i = 1, counter - 1 do
  if index > Idx - 1 then index = 1 end

  reaper.SetMediaItemInfo_Value(otherItems[i].item, "D_POSITION", ItemsSel[index].newStart or ItemsSel[index].oldPosition)
  reaper.SetMediaItemInfo_Value(otherItems[i].item, "D_LENGTH", ItemsSel[index].newLength)
  reaper.SetMediaItemTakeInfo_Value(otherItems[i].take, "D_PLAYRATE", ItemsSel[index].newRate)

  index = index + 1
end

reaper.PreventUIRefresh(-1)
reaper.UpdateArrange()
reaper.Undo_EndBlock("Item Random Position", -1)
jkooks is offline   Reply With Quote
Old 08-09-2020, 09:19 AM   #19
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

Thank you, it works great.
Unfortunately I do not understand the code.Wie kann man das lernen?
I still have a few scripts that work on one track, but unfortunately not on several.
Is there a general framework around a script so that the script does the same thing on all tracks with selected items that are in the same positions as with the first track?
Thanks
Dragonetti is offline   Reply With Quote
Old 08-09-2020, 05:20 PM   #20
jkooks
Human being with feelings
 
Join Date: May 2020
Posts: 190
Default

Basically all that happens is that the track of the first selected item and uses that to filter through the selected items. Anything that has the same track is put in the ItemsSel array and anything on a different track is stored in a different array, named otherItems.

The script then goes on to adjust the items of the first track and makes sure that all of their positions are correct/that they are end to end - then goes through the otherItems array and adjusts their position based off of the item numbering.

This script will break down if one track has more items than the other (or if the item lengths are different from the initially changed ones) since it is using the amount of items on the first track to figure out where to put the items on the other tracks, but other than that it should work.


Code:
mainTrack = reaper.GetMediaItem_Track(reaper.GetSelectedMediaItem(0, 0))

ItemsSelCount = reaper.CountSelectedMediaItems(0)
for i = 0, ItemsSelCount - 1 do
  item = reaper.GetSelectedMediaItem(0, i)
  take = reaper.GetActiveTake(item) 

  local thisTrack = reaper.GetMediaItem_Track(item)

--filters the items into different arrays depending on the items track
  if thisTrack == mainTrack then
       
    --does all the usual stuff for the first track's items (i.e. calculates their poistion and everything

  else
    otherItems[counter] = {
      item = item,
      take = take,
      track = thisTrack,
    }

    counter = counter + 1
  end
end
 
--makes sure all of the items on the first track line up


--goes through all of the items in the second array - the ones on different tracks
local index = 1
for i = 1, counter - 1 do
  if index > Idx - 1 then index = 1 end --if the index reaches teh number of items on each track it will loop around and start at the end (supposed to mimic moving to the next track)

--sets item info for the appropriate corresponding item's
  reaper.SetMediaItemInfo_Value(otherItems[i].item, "D_POSITION", ItemsSel[index].newStart or ItemsSel[index].oldPosition)
  reaper.SetMediaItemInfo_Value(otherItems[i].item, "D_LENGTH", ItemsSel[index].newLength)
  reaper.SetMediaItemTakeInfo_Value(otherItems[i].take, "D_PLAYRATE", ItemsSel[index].newRate)

  index = index + 1
end
jkooks is offline   Reply With Quote
Old 08-14-2020, 07:12 AM   #21
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

This is a modified script from mpl. I can't get it into your framework script. Maybe you can have a look.
Thanks
Code:
local function Msg(str)
  reaper.ShowConsoleMsg(tostring(str) .. "\n")
end
math.randomseed(os.time())
sequenzen = {"sussss","ussssss","sussssssss","sssussss","ssssssssus","usssssss"}   
seq = sequenzen[math.random(1,#sequenzen)]   
item_ptrs = {} for 
selitem = 1,  reaper.CountSelectedMediaItems( 0 ) do 
item_ptrs[#item_ptrs+1] =  reaper.GetSelectedMediaItem( 0, selitem-1 ) 
end
parsed_t = {} for char in seq:gmatch('%a') do 
local val = 0
if char=='s' then val = 1 
end 
parsed_t[#parsed_t+1] = val 
end
for i = 1, (#item_ptrs) do 
local ptid =(1+(i-1)%#parsed_t)
if parsed_t[ptid] then 
reaper.SetMediaItemInfo_Value(item_ptrs[i], "B_UISEL",parsed_t[ptid]) 
end end
reaper.UpdateArrange()

--Msg(random)
Dragonetti is offline   Reply With Quote
Old 08-14-2020, 11:35 AM   #22
jkooks
Human being with feelings
 
Join Date: May 2020
Posts: 190
Default

Can you explain what it does first, and what you need it to do? It is a little hard trying to figure out how to adjust a script when you don't know what the end product is supposed to be like.

I'm assuming you need to only have the items on the first track change and then all the items on the other tracks change to the same thing, but the added info is nice to have too.
jkooks is offline   Reply With Quote
Old 08-14-2020, 11:48 AM   #23
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

The script randomly deselects from all selected items.
And that should be the same on all tracks again.
Thanks
Dragonetti is offline   Reply With Quote
Old 08-14-2020, 01:43 PM   #24
jkooks
Human being with feelings
 
Join Date: May 2020
Posts: 190
Default

This should work:

Code:
reaper.PreventUIRefresh(1)

local function Msg(str)
  reaper.ShowConsoleMsg(tostring(str) .. "\n")
end


math.randomseed(os.time())

sequenzen = {"sussss","ussssss","sussssssss","sssussss","ssssssssus","usssssss"}   
seq = sequenzen[math.random(1,#sequenzen)]   

item_ptrs = {}
itemCount = 1

other_items = {}
otherCount = 1

mainTrack = reaper.GetMediaItem_Track(reaper.GetSelectedMediaItem(0, 0))

for selitem = 1, reaper.CountSelectedMediaItems(0) do
  local thisItem = reaper.GetSelectedMediaItem(0 , selitem - 1)
  local thisTrack = reaper.GetMediaItem_Track(thisItem)

  if thisTrack == mainTrack then
    item_ptrs[itemCount] =  thisItem
    itemCount = itemCount + 1
  
  else
    other_items[otherCount] = {
      item = thisItem,
      track = thisTrack,
    }

    otherCount = otherCount + 1
  end
end


parsed_t = {}

for char in seq:gmatch('%a') do 
  local val = 0

  if char=='s' then val = 1 end 

  parsed_t[#parsed_t+1] = val 
end

for i = 1, itemCount - 1 do 
  local ptid = (1+ (i-1)%#parsed_t)

  if parsed_t[ptid] then
    reaper.SetMediaItemInfo_Value(item_ptrs[i], "B_UISEL",parsed_t[ptid]) 
  end
end


local lastTrack, index
for i = 1, otherCount - 1 do
  if not lastTrack or lastTrack ~= other_items[i].track then
    index = 1
    lastTrack = other_items[i].track
  end

  if parsed_t[index] then
    reaper.SetMediaItemInfo_Value(other_items[i].item, "B_UISEL",parsed_t[index])
  end

  index = index + 1
end


reaper.PreventUIRefresh(-1)
reaper.UpdateArrange()
jkooks is offline   Reply With Quote
Old 08-16-2020, 02:24 AM   #25
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

Unfortunately it doesn't work properly as soon as I select more items than the highest length of the "sequencen".
The "sequence" is not repeated in the "other_items"
Many thanks

Dragonetti is offline   Reply With Quote
Old 08-16-2020, 01:11 PM   #26
jkooks
Human being with feelings
 
Join Date: May 2020
Posts: 190
Default

This should work:


Code:

reaper.PreventUIRefresh(1)

local function Msg(str)
  reaper.ShowConsoleMsg(tostring(str) .. "\n")
end


math.randomseed(os.time())

sequenzen = {"sussss","ussssss","sussssssss","sssussss","ssssssssus","usssssss"}   
seq = sequenzen[math.random(1,#sequenzen)]   

item_ptrs = {}
itemCount = 1

other_items = {}
otherCount = 1

mainTrack = reaper.GetMediaItem_Track(reaper.GetSelectedMediaItem(0, 0))

for selitem = 1, reaper.CountSelectedMediaItems(0) do
  local thisItem = reaper.GetSelectedMediaItem(0 , selitem - 1)
  local thisTrack = reaper.GetMediaItem_Track(thisItem)

  if thisTrack == mainTrack then
    item_ptrs[itemCount] =  thisItem
    itemCount = itemCount + 1
  
  else
    other_items[otherCount] = {
      item = thisItem,
      track = thisTrack,
    }

    otherCount = otherCount + 1
  end
end


parsed_t = {}

for char in seq:gmatch('%a') do 
  local val = 0

  if char=='s' then val = 1 end 

  parsed_t[#parsed_t+1] = val 
end

for i = 1, itemCount - 1 do 
  local ptid = (1+ (i-1)%#parsed_t)

  if parsed_t[ptid] then
    reaper.SetMediaItemInfo_Value(item_ptrs[i], "B_UISEL",parsed_t[ptid]) 
  end
end


local lastTrack, index
for i = 1, otherCount - 1 do
  if not lastTrack or lastTrack ~= other_items[i].track then
    index = 1
    lastTrack = other_items[i].track
  elseif not parsed_t[index] then
    index = 1
  end


  reaper.SetMediaItemInfo_Value(other_items[i].item, "B_UISEL",parsed_t[index])

  index = index + 1
end


reaper.PreventUIRefresh(-1)
reaper.UpdateArrange()
jkooks is offline   Reply With Quote
Old 08-17-2020, 02:59 PM   #27
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

Yes wonderful, everything is working out now, thank you very much
Dragonetti is offline   Reply With Quote
Old 08-20-2020, 07:31 AM   #28
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

Maybe a bit rude, but can someone rewrite this code so that it does the same for all selected tracks?
Thank you
Code:
--random_pitch_depending_on_scale
 
function Msg(variable)
  reaper.ShowConsoleMsg(tostring(variable).."\n") 
end

 
function get_chord_notes(chord_region)  

    retval, isrgn, region_pos, region_end, region_name, region_index, region_color = reaper.EnumProjectMarkers3( 0, chord_region)
     
  if string.match( region_name, "@.*") then next_region() end -- skip region marked @ ignore     
       if string.find(region_name, "/") then
          root, chord, slash = string.match(region_name, "(%w[#b]?)(.*)(/%a[#b]?)$")
       else
          root, chord = string.match(region_name, "(%w[#b]?)(.*)$") slashnote = 0 slash = ""
       end

     
     if not chord or #chord == 0 then chord = "Maj" end
     if not slash then slash = "" end
  

  note1 = 0 
  -- 60 = C3
  if root == "C" then note1 = 0
  elseif root == "C#" then note1 = 1
  elseif root == "Db" then note1 = 1
  elseif root == "D" then note1 = 2
  elseif root == "D#" then note1 = 3
  elseif root == "Eb" then note1 = 3
  elseif root == "E" then note1 = 4
  elseif root == "F" then note1 = 5
  elseif root == "F#" then note1 = 6
  elseif root == "Gb" then note1 = 6
  elseif root == "G" then note1 = 7
  elseif root == "G#" then note1 = 8
  elseif root == "Ab" then note1 = 8
  elseif root == "A" then note1 = 9
  elseif root == "A#" then note1 = 10
  elseif root == "Bb" then note1 = 10
  elseif root == "B" then note1 = 11
  if not root then end 
  end
  
  Ionian     = {-48,-46,-44,-43,-41,-39,-37,-36,-34,-32,-31,-29,-27,-25,-24,-22,-20,-19,-17,-15,-13,-12,-10,-8,-7,-5,-3,-1,0,2,4,5,7,9,11,12,14,16,17,19,21,23,24,26,28,29,31,33,35,36,38,40,41,43,45,47,48}
  Dorian     = {-48,-46,-45,-43,-41,-39,-38,-36,-34,-33,-31,-29,-27,-26,-24,-22,-21,-19,-17,-15,-14,-12,-10,-9,-7,-5,-3,-2,0,2,3,5,7,9,10,12,14,15,17,19,21,22,24,26,27,29,31,33,34,36,38,39,41,43,45,46,48}
  Phrygian   = {-48,-47,-45,-43,-41,-40,-38,-36,-35,-33,-31,-29,-28,-26,-24,-23,-21,-19,-17,-16,-14,-12,-11,-9,-7,-5,-4,-2,0,1,3,5,7,8,10,12,13,15,17,19,20,22,24,25,27,29,31,32,34,36,37,39,41,43,44,46,48}
  Lydian     = {-48,-46,-44,-42,-41,-39,-37,-36,-34,-32,-30,-29,-27,-25,-24,-22,-20,-18,-17,-15,-13,-12,-10,-8,-6,-5,-3,-1,0,2,4,6,7,9,11,12,14,16,18,19,21,23,24,26,28,30,31,33,35,36,38,40,42,43,45,47,48}
  Mixolydian = {-48,-46,-44,-43,-41,-39,-38,-36,-34,-32,-31,-29,-27,-26,-24,-22,-20,-19,-17,-15,-14,-12,-10,-8,-7,-5,-3,-2,0,2,4,5,7,9,10,12,14,16,17,19,21,22,24,26,28,29,31,33,34,36,38,40,41,43,45,46,48}
  Aeolian    = {-48,-46,-45,-43,-41,-40,-38,-36,-34,-33,-31,-29,-28,-26,-24,-22,-21,-19,-17,-16,-14,-12,-10,-9,-7,-5,-4,-2,0,2,3,5,7,8,10,12,14,15,17,19,20,22,24,26,27,29,31,32,34,36,38,39,41,43,44,46,48}
  Locrian    = {-48,-47,-45,-43,-42,-40,-38,-36,-35,-33,-31,-30,-28,-26,-24,-23,-21,-19,-18,-16,-14,-12,-11,-9,-7,-6,-4,-2,0,1,3,5,6,8,10,12,13,15,17,18,21,22,24,25,27,29,30,32,34,36,37,39,41,42,44,46,48}


  if string.find(",Maj7,maj7,Maj7,Maj,M,M7,", ","..chord..",", 1, true) then note2=2  note3=4  note4=5  note5=7  note6=9  note7=11 scale = Ionian end -- Ionian 
  if string.find(",m7,min7,-7,", ","..chord..",", 1, true)              then note2=2  note3=3  note4=5  note5=7  note6=9  note7=10 scale = Dorian end -- Dorian
  if string.find(",m7b9,", ","..chord..",", 1, true)                    then note2=1  note3=3  note4=5  note5=7  note6=8  note7=10 scale = Phrygian end -- Phrygian
  if string.find(",maj7#11,maj#11,", ","..chord..",", 1, true)          then note2=2  note3=4  note4=6  note5=7  note6=9  note7=11 scale = Lydian end -- Lydian
  if string.find(",7,dom,9,13,", ","..chord..",", 1, true)              then note2=2  note3=4  note4=5  note5=7  note6=9  note7=10 scale = Mixolydian end -- Mixolydian
  if string.find(",m,min,", ","..chord..",", 1, true)                   then note2=2  note3=3  note4=5  note5=7  note6=8  note7=10 scale = Aeolian end -- Aeolian
  if string.find(",m7b5b9,m7-5-9,", ","..chord..",", 1, true)           then note2=1  note3=3  note4=5  note5=6  note6=8  note7=10 scale = Locrian end -- Locrian


end


--MAIN---------------------------------------------------------------
function main()

    items = 0
    items = reaper.CountSelectedMediaItems(0)
    retval, num_markers, num_regions = reaper.CountProjectMarkers(0)
    --Msg("items="..items)
    if items == 0 then goto finish end
    
    for i = 0, items -1 do
    
      sel_item = reaper.GetSelectedMediaItem( 0, i )
      
      item_pos = reaper.GetMediaItemInfo_Value( sel_item, "D_POSITION")
      
      for ir = 0, num_regions -1 do -- regions end loop start 
        
        retval, isrgn, pos, rgnend, name, markrgnindexnumber, color = reaper.EnumProjectMarkers3( 0, ir )
        
        item_region = ir
        
        if item_pos >= pos and item_pos < rgnend then break end
      end
      
      get_chord_notes(item_region) 
            
            match=0
          
            for s = 1, 57 do
             
              if not sel_item then break end
              sel_take = reaper.GetActiveTake(sel_item)
              item_pitch = reaper.GetMediaItemTakeInfo_Value(sel_take, 'D_PITCH')
              interval = {"0","0","0","0","2","4","4","6","1","-2","-2","-3","-3","-6","-1"}  
              Rand = interval[math.random(1,#interval)]   
              number = tonumber(Rand)  
               
              if item_pitch-note1 == scale[s]  then 
                match=1
               
                new_pitch = scale[s+number]+note1 --new_pitch = scale[s+1]
                reaper.SetMediaItemTakeInfo_Value(sel_take, 'D_PITCH',new_pitch)
                reaper.UpdateItemInProject(sel_item)
                break
              end
              
            end
            
            if match==0 then
              new_pitch = item_pitch+1
              reaper.SetMediaItemTakeInfo_Value(sel_take, 'D_PITCH',new_pitch)
              reaper.UpdateItemInProject(sel_item)
            end

      end
      ::finish::  
      end

main()
Dragonetti is offline   Reply With Quote
Old 08-20-2020, 10:12 AM   #29
jkooks
Human being with feelings
 
Join Date: May 2020
Posts: 190
Default

Do you want it to run through all of the items on the selected tracks? Or only affect the selected items that are also on the selected tracks?

The way the script is set up now (with GetSelectedMediaItems) it should technically already be working on selected tracks too, just only changing the items that are also selected.
jkooks is offline   Reply With Quote
Old 08-21-2020, 02:08 AM   #30
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

thank you for looking here again
After executing the script it should look like the green bordered.
all items were selected
Dragonetti is offline   Reply With Quote
Old 08-21-2020, 10:27 AM   #31
jkooks
Human being with feelings
 
Join Date: May 2020
Posts: 190
Default

What does it normally do? And do you just need it to set the items on the other selected tracks to the same stuff that the items on the first track get set to?
jkooks is offline   Reply With Quote
Old 08-21-2020, 03:37 PM   #32
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

The script generates random values depending on the scale and add them to the existing pitch values.
It has to do it the same for all tracks so that new chords can arise from the key.I did this manually here in the gif
Dragonetti is offline   Reply With Quote
Old 08-22-2020, 05:56 PM   #33
jkooks
Human being with feelings
 
Join Date: May 2020
Posts: 190
Default

So, according to your first picture, this should work:

Code:
--random_pitch_depending_on_scale
 
function Msg(variable)
  reaper.ShowConsoleMsg(tostring(variable).."\n") 
end

 
function get_chord_notes(chord_region)  

  retval, isrgn, region_pos, region_end, region_name, region_index, region_color = reaper.EnumProjectMarkers3( 0, chord_region)
     
  if string.match( region_name, "@.*") then next_region() end -- skip region marked @ ignore     
   if string.find(region_name, "/") then
      root, chord, slash = string.match(region_name, "(%w[#b]?)(.*)(/%a[#b]?)$")
   else
      root, chord = string.match(region_name, "(%w[#b]?)(.*)$") slashnote = 0 slash = ""
   end

  if not chord or #chord == 0 then chord = "Maj" end
  if not slash then slash = "" end
  

  note1 = 0 
  -- 60 = C3
  if root == "C" then note1 = 0
  elseif root == "C#" then note1 = 1
  elseif root == "Db" then note1 = 1
  elseif root == "D" then note1 = 2
  elseif root == "D#" then note1 = 3
  elseif root == "Eb" then note1 = 3
  elseif root == "E" then note1 = 4
  elseif root == "F" then note1 = 5
  elseif root == "F#" then note1 = 6
  elseif root == "Gb" then note1 = 6
  elseif root == "G" then note1 = 7
  elseif root == "G#" then note1 = 8
  elseif root == "Ab" then note1 = 8
  elseif root == "A" then note1 = 9
  elseif root == "A#" then note1 = 10
  elseif root == "Bb" then note1 = 10
  elseif root == "B" then note1 = 11
  if not root then end 
  end
  
  Ionian     = {-48,-46,-44,-43,-41,-39,-37,-36,-34,-32,-31,-29,-27,-25,-24,-22,-20,-19,-17,-15,-13,-12,-10,-8,-7,-5,-3,-1,0,2,4,5,7,9,11,12,14,16,17,19,21,23,24,26,28,29,31,33,35,36,38,40,41,43,45,47,48}
  Dorian     = {-48,-46,-45,-43,-41,-39,-38,-36,-34,-33,-31,-29,-27,-26,-24,-22,-21,-19,-17,-15,-14,-12,-10,-9,-7,-5,-3,-2,0,2,3,5,7,9,10,12,14,15,17,19,21,22,24,26,27,29,31,33,34,36,38,39,41,43,45,46,48}
  Phrygian   = {-48,-47,-45,-43,-41,-40,-38,-36,-35,-33,-31,-29,-28,-26,-24,-23,-21,-19,-17,-16,-14,-12,-11,-9,-7,-5,-4,-2,0,1,3,5,7,8,10,12,13,15,17,19,20,22,24,25,27,29,31,32,34,36,37,39,41,43,44,46,48}
  Lydian     = {-48,-46,-44,-42,-41,-39,-37,-36,-34,-32,-30,-29,-27,-25,-24,-22,-20,-18,-17,-15,-13,-12,-10,-8,-6,-5,-3,-1,0,2,4,6,7,9,11,12,14,16,18,19,21,23,24,26,28,30,31,33,35,36,38,40,42,43,45,47,48}
  Mixolydian = {-48,-46,-44,-43,-41,-39,-38,-36,-34,-32,-31,-29,-27,-26,-24,-22,-20,-19,-17,-15,-14,-12,-10,-8,-7,-5,-3,-2,0,2,4,5,7,9,10,12,14,16,17,19,21,22,24,26,28,29,31,33,34,36,38,40,41,43,45,46,48}
  Aeolian    = {-48,-46,-45,-43,-41,-40,-38,-36,-34,-33,-31,-29,-28,-26,-24,-22,-21,-19,-17,-16,-14,-12,-10,-9,-7,-5,-4,-2,0,2,3,5,7,8,10,12,14,15,17,19,20,22,24,26,27,29,31,32,34,36,38,39,41,43,44,46,48}
  Locrian    = {-48,-47,-45,-43,-42,-40,-38,-36,-35,-33,-31,-30,-28,-26,-24,-23,-21,-19,-18,-16,-14,-12,-11,-9,-7,-6,-4,-2,0,1,3,5,6,8,10,12,13,15,17,18,21,22,24,25,27,29,30,32,34,36,37,39,41,42,44,46,48}


  if string.find(",Maj7,maj7,Maj7,Maj,M,M7,", ","..chord..",", 1, true) then note2=2  note3=4  note4=5  note5=7  note6=9  note7=11 scale = Ionian end -- Ionian 
  if string.find(",m7,min7,-7,", ","..chord..",", 1, true)              then note2=2  note3=3  note4=5  note5=7  note6=9  note7=10 scale = Dorian end -- Dorian
  if string.find(",m7b9,", ","..chord..",", 1, true)                    then note2=1  note3=3  note4=5  note5=7  note6=8  note7=10 scale = Phrygian end -- Phrygian
  if string.find(",maj7#11,maj#11,", ","..chord..",", 1, true)          then note2=2  note3=4  note4=6  note5=7  note6=9  note7=11 scale = Lydian end -- Lydian
  if string.find(",7,dom,9,13,", ","..chord..",", 1, true)              then note2=2  note3=4  note4=5  note5=7  note6=9  note7=10 scale = Mixolydian end -- Mixolydian
  if string.find(",m,min,", ","..chord..",", 1, true)                   then note2=2  note3=3  note4=5  note5=7  note6=8  note7=10 scale = Aeolian end -- Aeolian
  if string.find(",m7b5b9,m7-5-9,", ","..chord..",", 1, true)           then note2=1  note3=3  note4=5  note5=6  note6=8  note7=10 scale = Locrian end -- Locrian
end


--MAIN---------------------------------------------------------------
function main()
  items = 0
  items = reaper.CountSelectedMediaItems(0)
  retval, num_markers, num_regions = reaper.CountProjectMarkers(0)
  --Msg("items="..items)
  if items == 0 then goto finish end
  
  local mainTrack = reaper.GetMediaItem_Track(reaper.GetSelectedMediaItem(0, 0))

  local otherItems = {}
  local newPitches = {}

  local itemCount = 0
  local pitchCount = 0

  for i = 0, items -1 do
  
    local sel_item = reaper.GetSelectedMediaItem( 0, i )
    local thisTrack = reaper.GetMediaItem_Track(sel_item)
    
    if thisTrack == mainTrack then
      item_pos = reaper.GetMediaItemInfo_Value( sel_item, "D_POSITION")
      
      for ir = 0, num_regions -1 do -- regions end loop start 
        
        retval, isrgn, pos, rgnend, name, markrgnindexnumber, color = reaper.EnumProjectMarkers3( 0, ir )
        
        item_region = ir
        
        if item_pos >= pos and item_pos < rgnend then break end
      end
      
      get_chord_notes(item_region)     
      
      match=0
        
      for s = 1, 57 do
       
        if not sel_item then break end
        
        sel_take = reaper.GetActiveTake(sel_item)
        item_pitch = reaper.GetMediaItemTakeInfo_Value(sel_take, 'D_PITCH')
        interval = {"0","0","0","0","2","4","4","6","1","-2","-2","-3","-3","-6","-1"}  
        Rand = interval[math.random(1,#interval)]   
        number = tonumber(Rand)  
         
        if item_pitch-note1 == scale[s] then 
          match=1
         
          new_pitch = scale[s+number]+note1 --new_pitch = scale[s+1]
          reaper.SetMediaItemTakeInfo_Value(sel_take, 'D_PITCH',new_pitch)

          newPitches[pitchCount] = new_pitch
          pitchCount = pitchCount + 1

          break
        end
      end
      
      if match==0 then
        new_pitch = item_pitch+1
        reaper.SetMediaItemTakeInfo_Value(sel_take, 'D_PITCH',new_pitch)
      end



    else
      otherItems[itemCount] = sel_item
      itemCount = itemCount + 1
    end
  end


  local index, lastTrack
  for i = 0, itemCount - 1 do
    local sel_item = otherItems[i]
    local sel_take = reaper.GetActiveTake(sel_item)
    local thisTrack = reaper.GetMediaItem_Track(sel_item)

    if thisTrack ~= lastTrack then
      index = 0
      lastTrack = thisTrack
    end

    reaper.SetMediaItemTakeInfo_Value(sel_take, 'D_PITCH', newPitches[index])

    index = index + 1
  end

  reaper.UpdateArrange()

  ::finish::  
end

main()
jkooks is offline   Reply With Quote
Old 08-24-2020, 11:40 AM   #34
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

many thanks but unfortunately I didn't express myself correctly.
I have another code here that is very similar.
With these I can move the selected four-part chord within the key. For example, if I move from Cmaj7 up by one(+1) I get Dm7, then again by one Em7etc.
"+1" is entered in this line
new_pitch = scale [s + 1] + note1
I want to move the whole thing randomly now
If I enter a random number (math.randon (-4,4)) it doesn't work at all.
Code:
-- Display a message in the console for debugging
 
function Msg(variable)
  reaper.ShowConsoleMsg(tostring(variable).."\n")
end

 
function get_chord_notes(chord_region)  

    retval, isrgn, region_pos, region_end, region_name, region_index, region_color = reaper.EnumProjectMarkers3( 0, chord_region)
     
  if string.match( region_name, "@.*") then next_region() end -- skip region marked @ ignore     
       if string.find(region_name, "/") then
          root, chord, slash = string.match(region_name, "(%w[#b]?)(.*)(/%a[#b]?)$")
       else
          root, chord = string.match(region_name, "(%w[#b]?)(.*)$") slashnote = 0 slash = ""
       end

     
     if not chord or #chord == 0 then chord = "Maj" end
     if not slash then slash = "" end
  

  note1 = 0 
  -- 60 = C3
  if root == "C" then note1 = 0
  elseif root == "C#" then note1 = 1
  elseif root == "Db" then note1 = 1
  elseif root == "D" then note1 = 2
  elseif root == "D#" then note1 = 3
  elseif root == "Eb" then note1 = 3
  elseif root == "E" then note1 = 4
  elseif root == "F" then note1 = 5
  elseif root == "F#" then note1 = 6
  elseif root == "Gb" then note1 = 6
  elseif root == "G" then note1 = 7
  elseif root == "G#" then note1 = 8
  elseif root == "Ab" then note1 = 8
  elseif root == "A" then note1 = 9
  elseif root == "A#" then note1 = 10
  elseif root == "Bb" then note1 = 10
  elseif root == "B" then note1 = 11
  if not root then end
  end
  
  Ionian     = {-48,-46,-44,-43,-41,-39,-37,-36,-34,-32,-31,-29,-27,-25,-24,-22,-20,-19,-17,-15,-13,-12,-10,-8,-7,-5,-3,-1,0,2,4,5,7,9,11,12,14,16,17,19,21,23,24,26,28,29,31,33,35,36,38,40,41,43,45,47,48}
  Dorian     = {-48,-46,-45,-43,-41,-39,-38,-36,-34,-33,-31,-29,-27,-26,-24,-22,-21,-19,-17,-15,-14,-12,-10,-9,-7,-5,-3,-2,0,2,3,5,7,9,10,12,14,15,17,19,21,22,24,26,27,29,31,33,34,36,38,39,41,43,45,46,48}
  Phrygian   = {-48,-47,-45,-43,-41,-40,-38,-36,-35,-33,-31,-29,-28,-26,-24,-23,-21,-19,-17,-16,-14,-12,-11,-9,-7,-5,-4,-2,0,1,3,5,7,8,10,12,13,15,17,19,20,22,24,25,27,29,31,32,34,36,37,39,41,43,44,46,48}
  Lydian     = {-48,-46,-44,-42,-41,-39,-37,-36,-34,-32,-30,-29,-27,-25,-24,-22,-20,-18,-17,-15,-13,-12,-10,-8,-6,-5,-3,-1,0,2,4,6,7,9,11,12,14,16,18,19,21,23,24,26,28,30,31,33,35,36,38,40,42,43,45,47,48}
  Mixolydian = {-48,-46,-44,-43,-41,-39,-38,-36,-34,-32,-31,-29,-27,-26,-24,-22,-20,-19,-17,-15,-14,-12,-10,-8,-7,-5,-3,-2,0,2,4,5,7,9,10,12,14,16,17,19,21,22,24,26,28,29,31,33,34,36,38,40,41,43,45,46,48}
  Aeolian    = {-48,-46,-45,-43,-41,-40,-38,-36,-34,-33,-31,-29,-28,-26,-24,-22,-21,-19,-17,-16,-14,-12,-10,-9,-7,-5,-4,-2,0,2,3,5,7,8,10,12,14,15,17,19,20,22,24,26,27,29,31,32,34,36,38,39,41,43,44,46,48}
  Locrian    = {-48,-47,-45,-43,-42,-40,-38,-36,-35,-33,-31,-30,-28,-26,-24,-23,-21,-19,-18,-16,-14,-12,-11,-9,-7,-6,-4,-2,0,1,3,5,6,8,10,12,13,15,17,18,21,22,24,25,27,29,30,32,34,36,37,39,41,42,44,46,48}


  if string.find(",Maj7,maj7,Maj7,Maj,M,M7,", ","..chord..",", 1, true) then note2=2  note3=4  note4=5  note5=7  note6=9  note7=11 scale = Ionian end -- Ionian 
  if string.find(",m7,min7,-7,", ","..chord..",", 1, true)              then note2=2  note3=3  note4=5  note5=7  note6=9  note7=10 scale = Dorian end -- Dorian
  if string.find(",m7b9,", ","..chord..",", 1, true)                    then note2=1  note3=3  note4=5  note5=7  note6=8  note7=10 scale = Phrygian end -- Phrygian
  if string.find(",maj7#11,maj#11,", ","..chord..",", 1, true)          then note2=2  note3=4  note4=6  note5=7  note6=9  note7=11 scale = Lydian end -- Lydian
  if string.find(",7,dom,9,13,", ","..chord..",", 1, true)              then note2=2  note3=4  note4=5  note5=7  note6=9  note7=10 scale = Mixolydian end -- Mixolydian
  if string.find(",m,min,", ","..chord..",", 1, true)                   then note2=2  note3=3  note4=5  note5=7  note6=8  note7=10 scale = Aeolian end -- Aeolian
  if string.find(",m7b5b9,m7-5-9,", ","..chord..",", 1, true)           then note2=1  note3=3  note4=5  note5=6  note6=8  note7=10 scale = Locrian end -- Locrian


end


--MAIN---------------------------------------------------------------
function main()

    items = 0
    items = reaper.CountSelectedMediaItems(0)
    retval, num_markers, num_regions = reaper.CountProjectMarkers(0)
    --Msg("items="..items)
    if items == 0 then goto finish end
    
    for i = 0, items -1 do
    
      sel_item = reaper.GetSelectedMediaItem( 0, i )
      
      item_pos = reaper.GetMediaItemInfo_Value( sel_item, "D_POSITION")
      
      for ir = 0, num_regions -1 do -- regions end loop start 
        
        retval, isrgn, pos, rgnend, name, markrgnindexnumber, color = reaper.EnumProjectMarkers3( 0, ir )
        
        item_region = ir
        
        if item_pos >= pos and item_pos < rgnend then break end
      end
      
      
     
      
      get_chord_notes(item_region)
            
            match=0
          
            for s = 1, 57 do
            
              if not sel_item then break end
              sel_take = reaper.GetActiveTake(sel_item)
              item_pitch = reaper.GetMediaItemTakeInfo_Value(sel_take, 'D_PITCH')  
               
           
               
              if item_pitch-note1 == scale[s] then 
                match=1  
              --  rand = math.random(-4,4) ?????????????
                  
                   
                new_pitch = scale[s+1]+note1 --new_pitch = scale[s+1]
                reaper.SetMediaItemTakeInfo_Value(sel_take, 'D_PITCH',new_pitch)
                reaper.UpdateItemInProject(sel_item)
                break
              end
              
            end
            
            if match==0 then
              new_pitch = item_pitch+1
              reaper.SetMediaItemTakeInfo_Value(sel_take, 'D_PITCH',new_pitch)
              reaper.UpdateItemInProject(sel_item)
            end
          
      end
      ::finish::  
      end


  
main() 


  Msg(rand)
In the GIF example I first created the normal Cmaj7 for all 4 chords.(the audio is a single c tone)

Now comes the script. Of course I did this manually.
The right arrow is the code shown above.(the left is with -1)
The first chord got +2 (Em7),
the second 0 (Cmaj7),
the third +1 (Dm7) and the
fourth -1 (Bdim).
Could one program that so that one selects all items and the script randomly selects a value between (-4, and4) for each chord?
Thank you very much

Last edited by Dragonetti; 09-06-2020 at 12:59 PM.
Dragonetti is offline   Reply With Quote
Old 09-02-2020, 01:32 PM   #35
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

bump!
Dragonetti is offline   Reply With Quote
Old 09-06-2020, 02:43 PM   #36
MusoBob
Human being with feelings
 
MusoBob's Avatar
 
Join Date: Sep 2014
Posts: 2,643
Default

Sorry I haven't been following this and there is sooo much to read through, but there might be some Midi rhythm/melody modifier script/fx then you could read through the Midi notes and set the audio items to the start pos and length of the Midi notes ????
__________________
ReaTrakStudio Chord Track for Reaper forum
www.reatrak.com
STASH Downloads https://stash.reaper.fm/u/ReaTrak
MusoBob is offline   Reply With Quote
Old 09-07-2020, 06:01 AM   #37
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

Thank you for getting in touch.
I don't think it's too complicated.

1st step: instead of +1, random numbers between -4 and +4 should be used.

in this line "new_pitch = scale [s + 1] + note1"

I somehow can't make it

Thanks
Dragonetti is offline   Reply With Quote
Old 09-18-2020, 02:39 AM   #38
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

The script moves the chord up by 1.(red marked)
C major becomes D minor.
D minor becomes E minor
Emoll becomes F major, etc.
Works wonderfully.

But when I use the random function (marked in green in the gif)
, the individual items get different random values.
However, the chord items should all get the same random value.(e.g. +2)
https://stash.reaper.fm/40358/random...ding_scale.lua
Dragonetti is offline   Reply With Quote
Old 09-26-2020, 02:18 AM   #39
Dragonetti
Human being with feelings
 
Join Date: Feb 2017
Location: Kiel
Posts: 974
Default

bump!
Dragonetti is offline   Reply With Quote
Old 09-26-2020, 03:35 PM   #40
permeke
Human being with feelings
 
Join Date: Dec 2019
Posts: 588
Default

Quote:
Originally Posted by Dragonetti View Post
success stories
I didn't think I could do it
thanks solger

Code:
--- random_length within the time selection depending on grid----
----- script by  jkuk,dragonetti and solger -------
---https://forum.cockos.com/showthread.php?p=2285825#post2285825

for a=1,100 do
------------------------------------------------   
ItemsSel = {}
 
loop_start, loop_end = reaper.GetSet_LoopTimeRange(false,true,0,0,false  )

ItemsSelCount = reaper.CountSelectedMediaItems(0)














for i = 0, ItemsSelCount - 1 do      
  item = reaper.GetSelectedMediaItem(0, i)   
  take = reaper.GetActiveTake(item) 
    
  Idx = i + 1 -- 1-based table in Lua    
  ItemsSel[Idx] = {} 
  ItemsSel[Idx].thisItem = item
  ItemsSel[Idx].position =  reaper.GetMediaItemInfo_Value( item, "D_POSITION" )
  ItemsSel[Idx].playrate = reaper.GetMediaItemTakeInfo_Value(take, "D_PLAYRATE")
  ItemsSel[Idx].length = reaper.GetMediaItemInfo_Value( item, "D_LENGTH")
  

  
  start = ItemsSel[1].position  
  grid_end = reaper.BR_GetNextGridDivision( start)      
  grid_length = grid_end - start
    
    
  Grids = {"1","2","3","4"}
  Rand = Grids[math.random(1,#Grids)]  
  number = tonumber(Rand) 
 

  old_length = ItemsSel[Idx].length
  playrate = ItemsSel[Idx].playrate
  new_length = number * grid_length --new length randomly created from the table values x grid_length
  new_rate = ItemsSel[Idx].playrate*(old_length/new_length)




  reaper.SetMediaItemInfo_Value(item, "D_LENGTH",new_length)
  reaper.SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", new_rate)
  --reaper.SetMediaItemInfo_Value(item, "D_POSITION",new_position)
--ItemsSel[ItemsSelCount - 1].position  = last_pos
end 
 
for i = 1, ItemsSelCount-1 do

  --grabs items
  prevItem = ItemsSel[i].thisItem
  thisItem = ItemsSel[i+1].thisItem

  --grabs previous item's info
  prevStart = reaper.GetMediaItemInfo_Value(prevItem, "D_POSITION")
  prevLen = reaper.GetMediaItemInfo_Value(prevItem, "D_LENGTH")
  prevEnd = prevStart + prevLen

  reaper.SetMediaItemInfo_Value(thisItem, "D_POSITION", prevEnd) --sets item to be at the end of the previous item
  
  item = reaper.GetSelectedMediaItem(0, ItemsSelCount - 1)  
  last_item = reaper.GetMediaItemInfo_Value( item, "D_POSITION" )
  last_item_length = reaper.GetMediaItemInfo_Value( item, "D_LENGTH" )
  endposi = last_item + last_item_length
end


  if endposi == loop_end then break end
end

Where can I get this ? , including the menus . thanks
permeke 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 02:28 AM.


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