@Justin
Regarding PCM_Source_BuildPeaks:
Using reaper.UpdateArrange() after mode=0 but before mode=2 causes a flatline or incomplete peaks-line shown when doing this within a defer-loop.
Only until I drag the end of an item to extend the item that uses PCM_Source, the built peaks are shown.
Running reaper.UpdateArrange() again after mode=2 doesn't work in this case.
The following code exhibits the behaviour:
Code:
Source=reaper.GetMediaItemTake_Source(reaper.GetMediaItemTake(reaper.GetMediaItem(0,0),0))
BuildStart=reaper.PCM_Source_BuildPeaks(Source, 0)
-- the following line breaks showing the peak
-- if it's uncommented, the peaks show as expected(unless the peak has been
-- created with the following line included, then uncommenting it has no effect)
reaper.UpdateArrange()
function main()
BuildProgress=reaper.PCM_Source_BuildPeaks(Source, 1)
if BuildProgress~=0 then reaper.defer(main)
else reaper.PCM_Source_BuildPeaks(Source, 2) reaper.UpdateArrange() end
end
for i=0, 200 do main() end
I also think, the docs should better state "call PCM_Source_BuildPeaks(src,1)
repeatedly to build peaks piece by piece until it returns zero" to make clear, that this is the way to go.
Otherwise it sounds like calling it once in a while would be sufficient and the peak building happens in the background during that,while it actually "pauses" when PCM_Source_BuildPeaks isn't called.
Aside from that, it works flawless from what I've seen.
@Others
Here's a small tutorial on how to build peaks in ReaScript using PCM_Source_BuildPeaks:
The process to build a new peak is to use the modes in a certain order:
mode=0 starts the peak-building process(must be done once for this PCM_Source)
returned values are: 0, no peaks need to be built; 1, peaks are building
mode=1 progresses the peak-building a bit each time you call PCM_Source_BuildPeaks with mode=1)
call it repeatedly until it's finished and returns value 0!
returned values are: how many percent the peak-building still needs to do until it is finished
mode=2, this finishes up peak-building(call this, when mode=1 returns 0 and only then!)
returned value is 0
Running this before mode=1 returns 0 can cause broken peaks shown, until you click into a mediaitem that uses the PCM_Source.
After all peak-building is done, use reaper.UpdateArrange() to show them.
Note: All peaks of all takes that use a certain PCM_Source will be built!
Building peaks for multiple PCM_Sources simultaneously is allowed.
The following code builds a peak very simply. This is the easiest implementation.
However, if the PCM_Source, whose peaks need to be build, is a very long one, this can cause Reaper's UI to hang.
So use this on short PCM_Sources mainly.
Code:
-- Meo-Ada Mespotine - 19th of August 2021 - licensed under MIT-license
-- Rebuilt-Peak-Demo without defer, might cause hanging of Reaper's UI
-- Get Item 1, Take 1 and Source of Take 1
Item=reaper.GetMediaItem(0,0)
Take=reaper.GetMediaItemTake(Item,0)
Source=reaper.GetMediaItemTake_Source(Take)
-- start peak-building process(mode must be 0)
BuildStart=reaper.PCM_Source_BuildPeaks(Source, 0)
-- build peaks, until PCM_Source_BuildPeaks returns 0(mode must be 1)
while BuildProgress~=0 do
BuildProgress=reaper.PCM_Source_BuildPeaks(Source, 1)
end
-- when build-process is done, finish build-process(mode must be 2)
BuildXit=reaper.PCM_Source_BuildPeaks(Source, 2)
-- update the arrangeview, so the newly built peaks are shown
reaper.UpdateArrange()
If you want to build peaks for longer files and maybe showing a status-bar, you can use the following code.
It uses defer-loops instead of a while-loop.
As each ReaScript can have up to 1024 defer-loops running at the same time(more or less), I use each of
the 1024 defer-loops to build the peak a little further.
This will prevent hanging UI but might be a little slower than the while-approach.
Code:
-- Meo-Ada Mespotine - 19th of August 2021 - licensed under MIT-license
-- Rebuilt-Peak-Demo using defer, might be a little slower but doesn't
-- cause hanging of Reaper's UI
--
-- set Build_Factor to speed up building process
-- allowed values: 0(slow) and 1024(fast)
-- Use 1024 only, if you don't have any other defer-loops running.
-- If you have other defer-loops that need to be run now, set
-- Build_Factor to Build_Factor minus number of running defer-loops.
-- the number of defer-loops used to go through the peak build-process
-- the higher, the faster.
-- if you use other defer-loops at the time as well, set this lower than 1024 or the other defer-loop will not run
Build_Factor=255
-- Get Item 1, Take 1 and Source of Take 1
Item=reaper.GetMediaItem(0,0)
Take=reaper.GetMediaItemTake(Item,0)
Source=reaper.GetMediaItemTake_Source(Take)
-- start build-process of the peak(mode=0)
BuildStart=reaper.PCM_Source_BuildPeaks(Source, 0)
function main()
-- build peaks, until PCM_Source_BuildPeaks returns 0(mode must be 1)
BuildProgress=reaper.PCM_Source_BuildPeaks(Source, 1)
if BuildProgress~=0 then
-- if PCM_Source_BuildPeaks returned anything else than 0, defer this function again
reaper.defer(main)
else
-- if PCM_Source_BuildPeaks returned 0, finish building of the peaks(mode must be 2)
-- and update the arrangeview for the newly built peaks to show
BuildXit=reaper.PCM_Source_BuildPeaks(Source, 2)
reaper.UpdateArrange()
end
end
-- run multiple defer-instances of the peak-build-function
for i=0, Build_Factor do
main()
end
The following code combines both, defer-loops to cirvumvent possible hanging of Reaper's UI and a loop(for in this case)
to build as many small peak-bits and pieces as possible within each defer-loop.
You can influence the ratio between using defer-loops and for-loops by setting Build_Factor(defer) and Build_Progression(for).
Experiment, how high you can go with the number of for-loops, until Reaper's UI becomes laggy.
Code:
-- Meo-Ada Mespotine - 19th of August 2021 - licensed under MIT-license
-- Rebuilt-Peak-Demo defer and a regular for-loop combined, doesn't
-- cause hanging of Reaper's UI
--
-- set Build_Factor to speed up building process
-- allowed values: 0(slow) and 1024(fast)
-- Use 1024 only, if you don't have any other defer-loops running.
-- If you have other defer-loops that need to be run now, set
-- Build_Factor to Build_Factor minus number of running defer-loops.
-- build-speed factors
Build_Factor=255 -- set to the number of defer-loops used
Build_Progression=20 -- set to the number of peak-building-bits built within each defer-loop
-- Get Item 1, Take 1 and Source of Take 1
Item=reaper.GetMediaItem(0,0)
Take=reaper.GetMediaItemTake(Item,0)
Source=reaper.GetMediaItemTake_Source(Take)
-- start build-process of the peak(mode=0)
BuildStart=reaper.PCM_Source_BuildPeaks(Source,0)
function main()
-- build peaks, until PCM_Source_BuildPeaks returns 0(mode must be 1)
-- do it for Build_Progression-times within this defer-loop.
for i=0, Build_Progression do
BuildProgress=reaper.PCM_Source_BuildPeaks(Source,1)
end
if BuildProgress~=0 then
-- if PCM_Source_BuildPeaks returned anything else than 0, defer this function again
reaper.defer(main)
else
-- if PCM_Source_BuildPeaks returned 0, finish building of the peaks(mode must be 2)
-- and update the arrangeview for the newly built peaks to show
BuildXit=reaper.PCM_Source_BuildPeaks(Source,2)
reaper.UpdateArrange()
end
end
-- run multiple defer-instances of the peak-build-function
for i=0, Build_Factor do
main()
end