|
|
|
07-07-2020, 01:15 PM
|
#1
|
Human being with feelings
Join Date: May 2020
Posts: 190
|
Help: How do you use GetMediaItemTake_Peaks?
Hey everyone,
I have been trying to use the GetMediaItemTake_Peaks API function to get the max peak value for every n frames in the active take, but I am having a hard time figuring out what to pass it in order to get this to work.
First off, what exactly is the peakrate parameter? Is it "every n number of samples return the max and min" or is it "get the max and min samples every n length in time"?
Additionally, does the GetMediaItemTake_Peaks function account for various take properties (i.e. volume envelopes, item volume, play rates, etc) so it returns different values than if I used the source_peaks function? I haven't been able to find too much clear info on this function, so I am still trying to wrap my head around some of the specifics of it in order to figure out what I need to run for my script.
Thanks!
Last edited by jkooks; 07-08-2020 at 03:31 PM.
|
|
|
07-07-2020, 03:57 PM
|
#2
|
Human being with feelings
Join Date: May 2020
Posts: 190
|
Also, I am having issues with it getting the same sample values over and over. Seems like the function is looping through a portion of the clip for all of the samples instead of going through the entire clip. I found something by Lokasenna that says you have to go through the samples in chunks, so only a portion of the clip at a time, but the script I saw uses a static value of 66536 to determine the sample number and I am not sure why.
Any help is appreciated!
Last edited by jkooks; 07-07-2020 at 06:32 PM.
|
|
|
07-08-2020, 03:28 PM
|
#3
|
Human being with feelings
Join Date: May 2020
Posts: 190
|
For anyone interested in following this saga, I am now having an issue getting the position for each sampling. I put my code below but I am quite bad at math, so I wouldn't be surprised if there is a simple error I am making when determining the size of each sample group that is messing the whole thing up, or if there is just an infinitely easier way to do what I am trying to accomplish.
Code:
thisItem = reaper.GetSelectedMediaItem(0, 0)
thisTake = reaper.GetActiveTake(thisItem)
thisSource = reaper.GetMediaItemTake_Source(thisTake)
samplerate = reaper.GetMediaSourceSampleRate(thisSource)
chanNum = reaper.GetMediaSourceNumChannels(thisSource)
frameRate = reaper.TimeMap_curFrameRate(0)
frameRate = string.format("%0.2f", frameRate) --cuts off at hundredths mark
thisPos = reaper.GetMediaItemInfo_Value(thisItem, "D_POSITION")
thisLen = reaper.GetMediaItemInfo_Value(thisItem, "D_LENGTH")
local playrate = reaper.GetMediaItemTakeInfo_Value(thisTake, "D_PLAYRATE")
if playrate ~= 1 then
reaper.SetMediaItemTakeInfo_Value(thisTake, "D_PLAYRATE", 1)
reaper.SetMediaItemInfo_Value(thisItem, "D_LENGTH", thisLen * playrate)
end
--block size seems to be half of the amount
amount = 4 --every n frames
pkrate = (samplerate / frameRate) * amount --the amount of samples it checks for every peak return
sampleNum = math.floor((thisLen*frameRate) / amount) --the total number of samples that will be returned
secondsPerBlock = 1 --how many seconds I want each block to be
blockSize = math.floor((frameRate / amount) * secondsPerBlock) --amount of samples per block
blockNum = math.floor(sampleNum/blockSize) --figures out how many blocks consist of the entire sample size
extraBlock = sampleNum - (blockSize*blockNum) --extra samples since the last block most likely won't be full
sampleIncrement = thisLen / sampleNum --the start position for every peak return
posIncrement = sampleIncrement * blockSize --the increment for where it should start to sample the next block
buf = reaper.new_array((blockSize * chanNum) * 2) --has to be 2x the sampleNum --max and min, don't need spectral - probably don't need min either.
sampleStartTime = thisPos
highestSample = 0
highestPos = 0
local GetSamples = reaper.GetMediaItemTake_Peaks
local samplePos --position where every sample population starts
local sampleCount = 1 --count of how many samples have been returned
peaks = {}
--runs through each block to get the sample size
for i = 0, blockNum do
buf.clear()
if i == blockNum then blockSize = extraBlock end
retval = GetSamples(thisTake, pkrate, sampleStartTime, chanNum, blockSize, 0, buf)
samplePos = sampleStartTime
--runs through every returned peak to record the min, max and peak/sample start position
for j = 1, blockSize do
local count = #peaks
peaks[count+1] = buf[j] --max peak
peaks[count+2] = buf[blockSize + j] --min peak
peaks[count+3] = samplePos --start of where these samples were located
-- reaper.AddProjectMarker(0, false, samplePos, 0, "Sample " .. sampleCount, 0)
--records the overall highest sample and where they are (relatively) located
if peaks[count+1] > highestSample then
highestSample = peaks[count+1]
highestPos = peaks[count+3]
end
samplePos = samplePos + sampleIncrement --increments the samples' position
sampleCount = sampleCount + 1 --increments the sample count
end
-- reaper.AddProjectMarker(0, false, sampleStartTime, 0, "Block " .. i, 0)
sampleStartTime = sampleStartTime + posIncrement --increments the block's position
end
-- reaper.AddProjectMarker(0, false, samplePos, 0, "END OF SAMPLES", 0)
reaper.SetEditCurPos(highestPos, false, false) --sets the edit cursor at teh start of the sample that has the highest peak
if playrate ~= 1 then
reaper.SetMediaItemTakeInfo_Value(thisTake, "D_PLAYRATE", playrate)
reaper.SetMediaItemInfo_Value(thisItem, "D_LENGTH", item_len)
end
reaper.UpdateTimeline()
|
|
|
07-09-2020, 02:35 AM
|
#4
|
Human being with feelings
Join Date: May 2018
Location: Los Angeles
Posts: 1,719
|
hi jkooks,
Here is a script I wrote to give the the peaks of a bunch of items. It's much faster than using audio buffers. It borrows heavily from functions by SPK77.
If you write the code to split the item into equal intervals, that will surely do it.
Code:
function Msg (param)
reaper.ShowConsoleMsg(tostring (param).."\n")
end
------------------------------------------------------------
-- Mod from SPK77
-- http://forum.cockos.com/showpost.php?p=1608719&postcount=6
--Trak_Vol_dB = 20*math.log(val, 10) end
--Trak Vol val = 10^(dB_val/20) end
------------------------------------------------------------
-------------------------------------------------------------
-- item Vol conversion https://forum.cockos.com/showthread.php?p=2200278#post2200278
-----------------------------------------------------------
local LN10_OVER_TWENTY = 0.11512925464970228420089957273422
function DB2VAL(x) return math.exp(x*LN10_OVER_TWENTY) end
function VAL2DB(x)
if x < 0.0000000298023223876953125 then
return -150
else
return math.max(-150, math.log(x)* 8.6858896380650365530225783783321);
end
end
function Max_Peak_FAST ()
reaper.ClearConsole()
reaper.PreventUIRefresh(1)
reaper.Undo_BeginBlock()
local Max_Level = 0 -- keep track of max volume of items vertically
local Cur_Item = 0
local Num_Items = reaper.CountSelectedMediaItems( 0 )
local item_id = {}
local item_orig_vol = {}
if Num_Items == 0 then
reaper.ShowMessageBox("No items selected", "Alert", 0 )
end
-- log selected items and orig vols
for i = 0, Num_Items - 1 do
item_id [i] = reaper.GetSelectedMediaItem( 0, i )
take = reaper.GetMediaItemTake( item_id[i],0 )
item_orig_vol [i] = reaper.GetMediaItemTakeInfo_Value( take, "D_VOL" )
end
reaper.Main_OnCommand(40108,0) -- Normalize items
-- log selected items new vols (how much they were increased by)
for i = 0, Num_Items - 1 do
--item_id [i] = reaper.GetSelectedMediaItem( 0, i )
take = reaper.GetMediaItemTake( item_id[i],0 )
new_vol = reaper.GetMediaItemTakeInfo_Value( take, "D_VOL" )
retval, take_name = reaper.GetSetMediaItemTakeInfo_String( take, "P_NAME", "", 0 )
Msg(take_name .. "\t\t".. 0 - string.format("%.2f",VAL2DB(new_vol)))
reaper.SetMediaItemInfo_Value(item_id [i], "D_VOL",item_orig_vol [i] )
end
--reaper.Main_OnCommand(41923,0)-- Item: Reset items volume to +0dB
reaper.Main_OnCommand(reaper.NamedCommandLookup("_XENAKIOS_RESETTAKEVOL"),0)--Xenakios/SWS: Reset active take volume to 0.0 dB
reaper.PreventUIRefresh(-1)
reaper.Undo_EndBlock("Verify Max Peak (FAST)",-1)
end
Max_Peak_FAST ()
Cheers,
Andrew K
__________________
Cheers... Andrew K
Reaper v6.80+dev0621 - June 21 2023 • Catalina • Mac Mini 2020 6 core i7 • 64GB RAM • OS: Catalina • 4K monitor • RME RayDAT card with Sync Card and extended Light Pipe.
|
|
|
07-09-2020, 11:05 AM
|
#5
|
Human being with feelings
Join Date: May 2020
Posts: 190
|
Thank you Andrew, I will definitely check that out! I'm still interested in just figuring out how to use the GetMediaItemTake_Peaks function for curiosity's sake now, but something tells me I will end up going the same route you did too.
Thanks again!
|
|
|
08-22-2021, 11:52 AM
|
#6
|
Human being with feelings
Join Date: Sep 2019
Posts: 1,134
|
Quote:
Originally Posted by amagalma
Question: What exactly is peakrate in GetMediaItemTake_Peaks( take, peakrate, starttime, numchannels, numsamplesperchannel, want_extra_type, buf )? And how would I know what value to set? Thanks!
Asked by amagalma on March 8 2021, 12:12pm
|
Quote:
Originally Posted by Justin
Number of pixels per second!
|
Quote:
Originally Posted by amagalma
Thanks! So, are we supposed to pass GetHZoomLevel() there?
|
Quote:
Originally Posted by Justin
Yes, or if you're rendering at a different zoom level, that...
|
https://askjf.com/index.php?q=5660s
|
|
|
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 10:54 AM.
|