|
|
|
10-06-2020, 01:48 PM
|
#1
|
Human being with feelings
Join Date: Apr 2013
Posts: 36
|
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.
|
|
|
12-30-2020, 11:01 AM
|
#2
|
Human being with feelings
Join Date: Apr 2013
Posts: 36
|
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.
|
|
|
01-04-2021, 03:09 AM
|
#3
|
Human being with feelings
Join Date: Jan 2011
Posts: 445
|
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.
|
|
|
01-04-2021, 09:12 AM
|
#4
|
Human being with feelings
Join Date: Jan 2011
Posts: 445
|
Is something like this what you are looking for?
|
|
|
01-05-2021, 06:39 AM
|
#5
|
Human being with feelings
Join Date: Apr 2013
Posts: 36
|
Hey Aesis,
wow, sounds great!
The image is expired, would you mind to repost it?
Best!
|
|
|
01-07-2021, 06:08 AM
|
#6
|
Human being with feelings
Join Date: Jan 2011
Posts: 445
|
Quote:
Originally Posted by Derjayger
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...
|
|
|
01-07-2021, 07:58 AM
|
#7
|
Human being with feelings
Join Date: Apr 2013
Posts: 36
|
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?
|
|
|
01-12-2021, 10:14 AM
|
#8
|
Human being with feelings
Join Date: Jan 2011
Posts: 445
|
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.
Last edited by Aesis; 01-12-2021 at 10:31 AM.
|
|
|
01-12-2021, 02:21 PM
|
#9
|
Human being with feelings
Join Date: Apr 2013
Posts: 36
|
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.
|
|
|
05-11-2021, 07:06 PM
|
#10
|
Human being with feelings
Join Date: Feb 2016
Location: Hollyweird
Posts: 2,623
|
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?
|
|
|
02-24-2023, 04:19 AM
|
#11
|
Human being with feelings
Join Date: Nov 2012
Posts: 178
|
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)
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 09:20 PM.
|