Old 10-06-2020, 01:48 PM   #1
Derjayger
Human being with feelings
 
Join Date: Apr 2013
Posts: 36
Default Randomizing Midi Note Length

Hey,

I really need a good method for controlled randomizing of midi note length.
It's a thing that Reaper's humanizer is really missing. It's weird, because Reaper's quantizer can differentiate between note position, length, and so on. Would be great to implement these into the humanizer.

My method was:
0) Set a rather small grid size, but not too small or the following steps won't have any noticeable effect.
1) humanize note position
2) quantize everything with the "note end only" setting
3) freeze the quantization
4) quantize note position
5) humanize note position again.

Works okay, as long as there are no triplets. They get messed up by the grid.

I'd really love a plugin that does that, because it would be faster and nondestructive. Maybe as an addon to JS: MIDI Velocity and Timing Humanizer?
Here are two useful parameters:
a) set global deviation (in the same way as the timing slider in Reaper's humanize function)
b) set deviation rate based on note length (would probably need a delay in order to read the note length first). The idea is that there are many musical situations where long notes can handle more deviation than short notes.

(Please be so kind not to start a discussion about whether it's better to live-input everything.)

Last edited by Derjayger; 10-06-2020 at 01:54 PM.
Derjayger is offline   Reply With Quote
Old 12-30-2020, 11:01 AM   #2
Derjayger
Human being with feelings
 
Join Date: Apr 2013
Posts: 36
Default

Sorry if this is a double post, but I wanted to add two things:

1) The application I'd like to use it for is this: https://support.audiomodeling.com/kb/faq.php?id=37

2) I'd be happy to pay for a script that randomizes the note lengths of selected midi notes in a scaleable strength.

Derjayger is offline   Reply With Quote
Old 01-04-2021, 03:09 AM   #3
Aesis
Human being with feelings
 
Join Date: Jan 2011
Posts: 445
Default

Python script would be easily able to do that.

And Reaper itself can be scripted using Python, I have only used the default language though. In any case, I would expect a single click script should be possible.

EDIT: I will take a look.

Quote:
2) I'd be happy to pay for a script that randomizes the note lengths of selected midi notes in a scaleable strength.

Last edited by Aesis; 01-04-2021 at 03:16 AM.
Aesis is offline   Reply With Quote
Old 01-04-2021, 09:12 AM   #4
Aesis
Human being with feelings
 
Join Date: Jan 2011
Posts: 445
Default

Is something like this what you are looking for?

Aesis is offline   Reply With Quote
Old 01-05-2021, 06:39 AM   #5
Derjayger
Human being with feelings
 
Join Date: Apr 2013
Posts: 36
Default

Hey Aesis,

wow, sounds great!
The image is expired, would you mind to repost it?

Best!
Derjayger is offline   Reply With Quote
Old 01-07-2021, 06:08 AM   #6
Aesis
Human being with feelings
 
Join Date: Jan 2011
Posts: 445
Default

Quote:
Originally Posted by Derjayger View Post
Hey Aesis,

wow, sounds great!
The image is expired, would you mind to repost it?

Best!
Yes, here is the image again. Apologies for the delay...

Aesis is offline   Reply With Quote
Old 01-07-2021, 07:58 AM   #7
Derjayger
Human being with feelings
 
Join Date: Apr 2013
Posts: 36
Default

Fantastic!

I'll happily pay for it. Do you have an idea how much would be fair?
And where can I send the money to?
Derjayger is offline   Reply With Quote
Old 01-12-2021, 10:14 AM   #8
Aesis
Human being with feelings
 
Join Date: Jan 2011
Posts: 445
Default

The script as attachment. I will probably add a constant delay for the attack still, but this is the script in the above pic. Note that the time readings are derived from master tempo so if you have tempo changes you will have to multiply them accordingly to stick to correct numbers.

Quote:
Originally Posted by Code
seed=math.randomseed(os.time())
retval, var = reaper.GetUserInputs("How much drift to add (mean ms)?", 4, "Note start:,Note end:,Delay only? (yes, no),Same sided? (yes, no)","4,20,no,no")

if retval==true then

Var= {}
for match in string.gmatch(var, "[^,]+") do
table.insert(Var, match)
end

sd1=Var[1]*(math.pi/2)^0.5
sd2=Var[2]*(math.pi/2)^0.5
PPQ=960
BPM=reaper.Master_GetTempo()


function randNorm(Var)
local a, b
a=(-2*math.log(math.random()))^.5
b=2*math.pi*math.random()
return sd1*a*math.cos(b),sd2*a*math.sin(b)
end

function mstoppq(x,BPM,PPQ)
return math.ceil(x/(1000*60)*(BPM*PPQ))
end


mediaItems= reaper.CountSelectedMediaItems(0)
for i=0,mediaItems-1 do
mediaItem=reaper.GetSelectedMediaItem(0, i)
takes = reaper.CountTakes(mediaItem)
for j=0, takes-1 do
mediaItemTake = reaper.GetMediaItemTake(mediaItem, j)
retval, notecnt, nccevtcnt, textsyxevtcnt = reaper.MIDI_CountEvts(mediaItemTake)
for k =0, notecnt do
retval, selected, muted, startppqpos, endppqpos, chan, pitch, vel = reaper.MIDI_GetNote(mediaItemTake, k)
if selected==true then
random1, random2 = randNorm(Var)
if Var[3]=="yes" then
random1 = math.abs(random1)
random2 = math.abs(random2)
end
if Var[4]=="yes" then
if (random1<0 and random2>0) or (random1>0 and random2<0) then
random2=-random2
end
end
startppqpos = startppqpos + mstoppq(random1,BPM,PPQ)
endppqpos = endppqpos + mstoppq(random2,BPM,PPQ)
reaper.MIDI_SetNote(mediaItemTake, k, selected, muted,startppqpos,endppqpos, chan, pitch, vel, true)
end
end
reaper.MIDI_Sort(mediaItemTake)
end
end
end
Copy the script to (Your user)/AppData/Roaming/Reaper/Scripts. App data is a secret folder so if you don't see it type "Show hidden folders" to search, click, press "Show settings" on "Change settings to show hidden and system files", and then tick "Show hidden files, folders and drives".

In reaper the script shows up in actions -> show action list, and there you can run or hot key it.
Attached Files
File Type: lua Humanizer.lua (1.7 KB, 175 views)

Last edited by Aesis; 01-12-2021 at 10:31 AM.
Aesis is offline   Reply With Quote
Old 01-12-2021, 02:21 PM   #9
Derjayger
Human being with feelings
 
Join Date: Apr 2013
Posts: 36
Default

This is fantastic.
There are probably many people who you've made very happy, especially those who use SWAM Solo Strings to create ensembles.
Might even send the script to the SWAM devs, they might feature it.

Thanks! I'll send you the money after it's clear that I got the right mail adress (see PMs)

Last edited by Derjayger; 01-12-2021 at 02:33 PM.
Derjayger is offline   Reply With Quote
Old 05-11-2021, 07:06 PM   #10
MonkeyBars
Human being with feelings
 
MonkeyBars's Avatar
 
Join Date: Feb 2016
Location: Hollyweird
Posts: 2,623
Default

Thank you so much for making this tool, but I can't figure out the controls.

For example, I want to shorten all the selected notes by a random amount within a range. How can I do so?
MonkeyBars is offline   Reply With Quote
Old 02-24-2023, 04:19 AM   #11
richardj
Human being with feelings
 
Join Date: Nov 2012
Posts: 178
Default

A smaller Lua script to do this with no user input needed (with some help from ChatGPT):




changeInPercent = 20 -- <== Set this if you don't like 20% increase or decrease

-- Get the selected MIDI notes
local midiEditor = reaper.MIDIEditor_GetActive()
local take = reaper.MIDIEditor_GetTake(midiEditor)
local noteCount = reaper.MIDI_CountEvts(take)

-- Loop through the selected notes
for k = 0, noteCount do
retval, selected, muted, startppqpos, origEnd, chan, pitch, vel = reaper.MIDI_GetNote(take, k)
if selected == true then

-- Get note change +- 20%
randomFactor = (100 + math.random(-changeInPercent, changeInPercent)) / 100.0
origLength = origEnd - startppqpos
newEnd = startppqpos + (origLength * randomFactor)


-- Set the new note length
reaper.MIDI_SetNote(take, k, selected, muted, startppqpos, newEnd, chan, pitch, vel, true)
end
end

-- Update the MIDI editor
reaper.MIDI_Sort(take)
richardj 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:20 PM.


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