Go Back   Cockos Incorporated Forums > REAPER Forums > ReaScript, JSFX, REAPER Plug-in Extensions, Developer Forum

Reply
 
Thread Tools Display Modes
Old 02-21-2021, 06:41 AM   #201
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Quote:
Originally Posted by tapemelancholy View Post
Hello! Thanks for your great script!
i'm editing several songs per day and i'm wondering is it possible to implement some features for easier use.

1) Most wanted feature - crossfade offset (like a trigger pad in fill gaps) Now I have to manually move all crossfades, because otherwise I always get unnecessary clicks after quantization.

2) My dream feature - do not split audio if transients are already close to the grid because the more cuts, the worse it sounds. I spend most of my time removing useless cuts ��

Thanks!
Hey!
Thanks for using my script.
The ideas are interesting, I will think about it.

As a temporary solution for the first point: now you can use the MKSlicer for slicing and quantizing, and for crossfading use SWS Fill Gaps. In the script settings it is possible to disable the built-in crossfade engine.

An alternative solution for the second point: after quantizing, use Heal action. All items that were not offset relative to each other (not quantized, because they were exactly in the grid) will stick together as they were in the original state.

.

Last edited by cool; 02-21-2021 at 07:19 AM.
cool is offline   Reply With Quote
Old 02-26-2021, 01:05 PM   #202
Fabian
Human being with feelings
 
Fabian's Avatar
 
Join Date: Sep 2008
Location: Sweden
Posts: 7,431
Default

Great script! Thanks.

A comment... Shift+ESC (on windows) kills the script, but it should not really, only ESC with no modifier should quit the script, no?

Also, Ctrl+Space acts as play, but again, it is really only Space without any modifier that should act as play, right?

I use both of those key strokes for useful things, and Shift+ESC closing MK Slicer, or Ctrl+Space acting as play, disrupts my work flow significantly.

There are similar issues with a number of key-strokes that MK Slicer "steals".

Sorry to barge in here only to complain, these things are not a show-stopper for me, still it would be good if they were "corrected".

Thanks again for a great script.
__________________
// MVHMF
I never always did the right thing, but all I did wasn't wrong...
Fabian is offline   Reply With Quote
Old 02-27-2021, 09:09 AM   #203
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Quote:
Originally Posted by Fabian View Post
Great script! Thanks.

A comment... Shift+ESC (on windows) kills the script, but it should not really, only ESC with no modifier should quit the script, no?

Also, Ctrl+Space acts as play, but again, it is really only Space without any modifier that should act as play, right?

I use both of those key strokes for useful things, and Shift+ESC closing MK Slicer, or Ctrl+Space acting as play, disrupts my work flow significantly.

There are similar issues with a number of key-strokes that MK Slicer "steals".

Sorry to barge in here only to complain, these things are not a show-stopper for me, still it would be good if they were "corrected".

Thanks again for a great script.
Hey!
No problem, this is what this forum thread is for

Yes, the script intercepts keystrokes and at the moment I don't know a way to do this selectively. Also, I don't know a way to make some key combinations "transparent" to the script. Based on the forum posts I found, this problem is global.
For example, I can add Shift to the script exceptions and the window will not close when I press Shift + Esc. But even in Reaper, this combination will not work in the open script window, if the conditions for this are not specified in the script.

I will add option for Stop / Pause, which is really handy. Thanks for the idea.

But I cannot influence Shift + Esc. By the way, on my system (windows 10), this combination closes any Reaper window, even if a specific action is assigned. Also, this combination will close any GUI script that I have installed. Just out of curiosity: what function does this combination perform for you?
cool is offline   Reply With Quote
Old 02-27-2021, 11:11 AM   #204
Fabian
Human being with feelings
 
Fabian's Avatar
 
Join Date: Sep 2008
Location: Sweden
Posts: 7,431
Default

Quote:
Originally Posted by cool View Post
Hey!
No problem, this is what this forum thread is for

Yes, the script intercepts keystrokes and at the moment I don't know a way to do this selectively. Also, I don't know a way to make some key combinations "transparent" to the script. Based on the forum posts I found, this problem is global.
For example, I can add Shift to the script exceptions and the window will not close when I press Shift + Esc. But even in Reaper, this combination will not work in the open script window, if the conditions for this are not specified in the script.

I will add option for Stop / Pause, which is really handy. Thanks for the idea.

But I cannot influence Shift + Esc. By the way, on my system (windows 10), this combination closes any Reaper window, even if a specific action is assigned. Also, this combination will close any GUI script that I have installed. Just out of curiosity: what function does this combination perform for you?
Thanks,

Yeah, I know that this messy, there really should be an API call for passing keystrokes on to Reaper. I spent a *lot* of time testing different ways of getting around this in my MFXlist (https://forum.cockos.com/showthread.php?p=2398556), but I did not get to a fully satisfactory solution (yet). In the end I opted to not have ESC close the script, but instead close it on the right-click menu. However, there are still some annoying cases where MFXlist steals the focus.

Given how customizable Reaper is, scripts should not have to guess what key strokes the user has assigned to what, but simply pass on to Reaper key strokes that are not handled by the script; but this seem currently not to be possible.

And yes, Reaper itself is not always consistent when it comes to modifier keys, like treating Shift+ESC the same as ESC. Another example, in the mixer Ctr+Alt+Click an FX behaves the same as Alt+Click (removes the FX), while Shift+Alt+Click behaves like Shift+Click.

I have set Shift+ESC to remove time selection and loop points. Just to (try) to avoid closing deferred scripts that are open, when I just want to remove the time selection.
__________________
// MVHMF
I never always did the right thing, but all I did wasn't wrong...
Fabian is offline   Reply With Quote
Old 02-27-2021, 08:43 PM   #205
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Thanks for the conversation. Yes, I saw your script. Great job! I was impressed with its fast performance and good optimization.


Quote:
Originally Posted by Fabian View Post
I have set Shift+ESC to remove time selection and loop points. Just to (try) to avoid closing deferred scripts that are open, when I just want to remove the time selection.

Ah, got it. It wouldn't work anyway - the MKSlicer's job is tightly bound up with the loop points. To remove it, there is a Loop button in the interface.
But, if you change something while the script is running, it can lead to its incorrect work. This is largely due to another limitation in Reascripts: there is currently no way to make selective Undo or completely disable Undo for some actions.
cool is offline   Reply With Quote
Old 03-02-2021, 09:24 PM   #206
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

MK Slicer v2.03 (minor changes)
+ Now, when moving the waveform, the cursor changes its appearance.
+ Added option to choose between Play/Stop and Play/Pause when pressing Spacebar.
+ Polishing the work of Razor Edit.

Razor Edit is now implemented. As before, you can select one area on one track to get started. Several areas on one track will be combined into one.

Happy Slicing!
cool is offline   Reply With Quote
Old 03-08-2021, 02:41 PM   #207
Indiscipline
Human being with feelings
 
Indiscipline's Avatar
 
Join Date: Apr 2016
Posts: 143
Default

Quote:
Originally Posted by cool View Post
An alternative solution for the second point: after quantizing, use Heal action. All items that were not offset relative to each other (not quantized, because they were exactly in the grid) will stick together as they were in the original state.
Does this ever happen? Things are never precisely on grid, and even one sample shift will prevent healing. Low-bounding threshold for splitting looks like a sensible idea.
Indiscipline is offline   Reply With Quote
Old 03-08-2021, 10:35 PM   #208
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Quote:
Originally Posted by Indiscipline View Post
Does this ever happen? Things are never precisely on grid, and even one sample shift will prevent healing. Low-bounding threshold for splitting looks like a sensible idea.

Yes, I understand that.

Now I have studied the issue and solutions more closely. It looks like implementing the "Grid Treshhold" function is not a good idea. The point is that deleting a marker in the Slicer does not mean that the part without the marker will not be changed and will retain its position.

For understanding, consider an example that is close to a real workflow:

1. Suppose we have a sound that is placed close to the grid and we remove the marker from it.



2. After slicing and quantizing, this sound will inevitably move past the grid, because it will be pulled along by the part of the item where the marker is located. And the only way to keep the location of the sound is to make a cut (keep ALL markers). This is not a slicer problem, it is an editing feature that you have to put up with.
cool is offline   Reply With Quote
Old 03-09-2021, 05:05 AM   #209
Indiscipline
Human being with feelings
 
Indiscipline's Avatar
 
Join Date: Apr 2016
Posts: 143
Default

Quote:
Originally Posted by cool View Post
Now I have studied the issue and solutions more closely. It looks like implementing the "Grid Treshhold" function is not a good idea. The point is that deleting a marker in the Slicer does not mean that the part without the marker will not be changed and will retain its position.
...
After slicing and quantizing, this sound will inevitably move past the grid, because it will be pulled along by the part of the item where the marker is located.
I understand that the hit won't stay there, but the end result (the time feel of the part) heavily depends on the placement of the previous and next transients. I claim your example is just one of the possible situations: the previous note (at ~3.2.63) is seriously far behind the note in question (at 3.4.75). If it's a part played by a human, what probably happened is that the player had the time to sync with the pulse between those notes. The reason we'd like to decrease the number or cuts is to retain the most of the feel of the original performance but warp the result closer to the pulse. You generally want to cut and nudge the notes at "strong" beats leaving the surrounded "weak" notes attached to them even when this means the weak note won't be exactly at the grid after moving the strong one. In your example, it looks like the note at 3.4.75 "belongs" to the next one, not the previous one (just a guess), which means an ideal solution would quantize the note at 4.1.25 and pull the 3.4.75 with it. This is the behaviour of transient markers (if only two were used to quantize 3.2.63 and 4.1.25), which is why from the rhythmical point of view they often bring better results (but can't sound as transparent). What I'm saying is if the hits were more uniformly distributed there would be far more reason to leave the marked note without a cut.

Unfortunately my ramblings don't include the solution to smarter quantizing just some points one has to keep in mind when devising a viable and practical strategy.

One algorithmic idea for more natural quantization:
1. Measure the offset of each transient from the real grid before quantization.
2. For each movement include those offsets as a bias (weighted by a distance to the note) to decide how far a note has to be nudged. This can be conceptualized as a bias for a virtual grid to which the note will be pulled.

Another idea, viable as a manual strategy, but more complicated to pull off when automated:
Two-pass quantization.
1. Split at strong beats, quantize with a given strength.
2. Split each resulting item at transients at weaker beats and quantize them with lesser intensity. This can't be done right away, as the item was shifted at step 1, which means the weaker notes were shifted from their original position relative to the grid. This means the shift has to be memorized and put into computation, both to determine which position on the grid they belong to (if quantized 100%) and to decide how far it can be nudged to retain natural relationship with the notes at stronger beats.

Hope it all makes sense.
Indiscipline is offline   Reply With Quote
Old 03-09-2021, 06:56 AM   #210
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default


It looks complicated even in a textual description. I think these are the things we can live without.

I will explain.

Implementing this is incredibly complex. Also, the demand for this in real work is incredibly small. 99% of people who use quantization functions are looking for grid alignments. For those looking for more, the script has the ability to quantize on a swing grid and adjust the quantization strength. This is sufficient for most tasks.
cool is offline   Reply With Quote
Old 03-09-2021, 08:20 AM   #211
Indiscipline
Human being with feelings
 
Indiscipline's Avatar
 
Join Date: Apr 2016
Posts: 143
Default

Quote:
Originally Posted by cool View Post
the demand for this in real work is incredibly small. 99% of people who use quantization functions are looking for grid alignments.
...
This is sufficient for most tasks.
I completely understand your lack of enthusiasm in implementing anything of what I described (or even getting through the description), but these claims aren't backed by evidence in any serious way and I think you're mistaken here.

Please, don't think I'm demanding anything, just thought since you made such an effort with the script as it is now, you might be interested in expanding its feature set further, or at least discuss the realm of possibilities.

Last edited by Indiscipline; 03-09-2021 at 02:56 PM.
Indiscipline is offline   Reply With Quote
Old 03-21-2021, 04:48 AM   #212
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

2.1 coming soon
+ Added a Sync button (zoom and waveform position) with Arrange View window.
+ Added controls for easy access to changing grid parameters.
+ Improved the behavior of the Add Markers function during playback.
+ Now the script does not show an error window if no tracks are selected.
+ Now the script does not close if the action of the Get Item button caused an error.
+ Now errors when the script window is open are displayed only in the script interface, without additional windows.
+ Improved behavior when working with Razor Edit.
+ Partially rewritten code to free locales (bypassing 200 locale limit)
cool is offline   Reply With Quote
Old 03-22-2021, 06:12 AM   #213
vanhaze
Human being with feelings
 
vanhaze's Avatar
 
Join Date: Jul 2012
Location: Netherlands
Posts: 5,247
Default

Woohooo, can't wait !

Thanks so much for further developing MK Slicer, highly appreciated 👌🏼
__________________
Macbook Pro INTEL | Reaper, always latest version | OSX Ventura | Presonus Studio 24c
My Reaper Tips&Tricks YouTube Channel: https://www.youtube.com/user/vanhaze2000/playlists
vanhaze is offline   Reply With Quote
Old 03-22-2021, 06:37 AM   #214
beingmf
Human being with feelings
 
beingmf's Avatar
 
Join Date: Jul 2007
Location: Jazz City
Posts: 5,073
Default

Quote:
Originally Posted by cool View Post
2.1 coming soon
+ Added a Sync button (zoom and waveform position) with Arrange View window.
+ Added controls for easy access to changing grid parameters.
+ Improved the behavior of the Add Markers function during playback.
+ Now the script does not show an error window if no tracks are selected.
+ Now the script does not close if the action of the Get Item button caused an error.
+ Now errors when the script window is open are displayed only in the script interface, without additional windows.
+ Improved behavior when working with Razor Edit.
+ Partially rewritten code to free locales (bypassing 200 locale limit)
Спасибо большое! It's getting more and more useful, great ideas!
__________________
Windows 10x64 | AMD Ryzen 3700X | ATI FirePro 2100 | Marian Seraph AD2, 4.3.8 | Yamaha Steinberg MR816x
"If I can hear well, then everything I do is right" (Allen Sides)
beingmf is offline   Reply With Quote
Old 03-29-2021, 05:22 AM   #215
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

You're welcome, fellas!



v2.11 on the way, soon will be appear in the ReaPack

+ Restored the ability to edit the position and velocity of markers (it was broken in the previous version, sorry).
+ Now toggling the Grid buttons does not reset the Swing amount.
+ Now the Swing slider does not show -0 when the value is 0.
+ Quick Q is now available when switching Slice / Markers modes and after changing Grid / Swing. Just press Q to get the result right away. After changing the parameters, pressing Q again will also work.
+ Fixed a bug. Now, when you change the parameters of the sliders using the mouse wheel, the changes will be immediately noticeable when the buttons are pressed.

A little about performance and why you should use Glue on items with a changed Ratio.
Some users are worried about the long start of the script and now I want to talk about how you can increase the speed of work.
When launched, the script scans the audio for transients and places markers. If the Rate has been changed for the audio, scanning will take place adjusted for the work of the stretching algorithm (plus, the direction of stretching: with increasing item length, the time increases, and vice versa), which is specified in the settings. You can compare how big the difference in script run time is when processing five-minute audio.
There is almost a direct dependence on the quality of the stretching algorithm. The Rubberband is very high quality, but it will keep you waiting for several tens of seconds. On the other hand, Simple Windowed is incredibly fast, but its artifacts are very noticeable and this will affect the accuracy of the placement of markers.
The compromise option I chose for myself: Elastique 2.2.8 Efficient Balanced. This is a minimum of artifacts with small range of Ratio change, versatility when working with percussion and melodic elements, and a fairly high speed of work. And where high precision is needed, I use Rubberband and then Glue.

i5-9500, 5 min audio, Rate 0.993

Algorithm: Script start time in seconds.
Glued Item (zero Rate): 3.5s
Simple Windowed: 4.5s
SoundTouch: def 15s, hiq 31s, fast 7s
Elastique 2.2.8:
pro 11s,
eff 7s,
sol 7s, sol speech 5s
Elastique 3.3.3:
pro 19s,
eff 14s,
sol 15s, sol speech 5s
Rubberband: 31s

Last edited by cool; 03-29-2021 at 05:37 AM.
cool is offline   Reply With Quote
Old 03-31-2021, 01:38 AM   #216
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,458
Default

Quote:
Originally Posted by cool View Post
i5-9500, 5 min audio, Rate 0.993

Algorithm: Script start time in seconds.
Glued Item (zero Rate): 3.5s
Simple Windowed: 4.5s
SoundTouch: def 15s, hiq 31s, fast 7s
Elastique 2.2.8:
pro 11s,
eff 7s,
sol 7s, sol speech 5s
Elastique 3.3.3:
pro 19s,
eff 14s,
sol 15s, sol speech 5s
Rubberband: 31s

You can speed up your script more than 300% in all cases with a small change. Instead of reading directly from the reaper.array buffer, make a temporary lua table copy and read from there. I have documented this here. See lines 121-122 and 132. Also, avoid calculating many times in a loop values that are constants. So for example, in Lokasenna's template code line 168:
Code:
starttime_sec = starttime_sec + ((block_size * n_channels) / samplerate)
The number represented by this calculation ((block_size * n_channels) / samplerate) is constant. There is no need to calculate it for every round in the loop. It could be:
Code:
local win_length = ((block_size * n_channels) / samplerate)
for loop here....
  ...
  starttime_sec = starttime_sec + win_length
end -- end of for loop
Hope this helps
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)

Last edited by amagalma; 03-31-2021 at 01:46 AM.
amagalma is offline   Reply With Quote
Old 03-31-2021, 01:55 AM   #217
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,900
Default

@amagalma
block_size can be smaller for the last block though. A condition could be added to take care of that. Do you want to update the code snippet with that enhancement ?
X-Raym is offline   Reply With Quote
Old 03-31-2021, 02:20 AM   #218
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,458
Default

Quote:
Originally Posted by X-Raym View Post
@amagalma
block_size can be smaller for the last block though. A condition could be added to take care of that. Do you want to update the code snippet with that enhancement ?

There is no need. The algorithm doesn't change.. starttime_sec calculates the position of the next block, so once you are at the last block (which means you are at the final for loop) you don't care about what calculation this number returns since there is no next block
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is offline   Reply With Quote
Old 03-31-2021, 08:43 AM   #219
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Quote:
Originally Posted by amagalma View Post
You can speed up your script more than 300% in all cases with a small change. Instead of reading directly from the reaper.array buffer, make a temporary lua table copy and read from there. I have documented this here. See lines 121-122 and 132. Also, avoid calculating many times in a loop values that are constants. So for example, in Lokasenna's template code line 168:
Code:
starttime_sec = starttime_sec + ((block_size * n_channels) / samplerate)
The number represented by this calculation ((block_size * n_channels) / samplerate) is constant. There is no need to calculate it for every round in the loop. It could be:
Code:
local win_length = ((block_size * n_channels) / samplerate)
for loop here....
  ...
  starttime_sec = starttime_sec + win_length
end -- end of for loop
Hope this helps

Thanks a lot! Unfortunately, this part of the code (sampling, audio filtering and transient search) was not written by me, and I just have no idea how it works. At the moment, this is too difficult for me to understand.

p.s.
However, I tried it. There were many attempts and I always got either an error or only an error. I could not achieve an increase in performance.

p.p.s.
Here is this part of the code, if I understood everything correctly. I highlighted the line that I took out of the loop. But since self.full_buf_sz is taken inside the loop, I got a predictable error.

Code:
function Wave:Processing()
    -------------------------------
    -- Filter values --------------
    -------------------------------
    -- LP = HiFreq, HP = LowFreq --
    local Low_Freq, Hi_Freq =  HP_Freq.form_val, LP_Freq.form_val
    local bin_freq = srate/(block_size*2)          -- freq step 
    local lowband  = Low_Freq/bin_freq             -- low bin
    local hiband   = Hi_Freq/bin_freq              -- hi bin
    -- lowband, hiband to valid values(need even int) ------------
    lowband = floor(lowband/2)*2
    hiband  = ceil(hiband/2)*2  
    -------------------------------------------------------------------------
    -- Get Original(input) samples to in_buf >> to table >> create peaks ----
    -------------------------------------------------------------------------
    if not self.State then
        if not self:Set_Values() then return end -- set main values, coordinates etc   
        ------------------------------------------------------ 
        local size
        local buf_start = self.sel_start
        for i=1,  self.n_Full_Bufs+1 do 
            if i>self.n_Full_Bufs then size = self.rest_buf_sz else size = self.full_buf_sz end  

            local tmp_buf = r.new_array(size)
            r.GetAudioAccessorSamples(self.AA, srate, 1, buf_start, size, tmp_buf) -- orig samples to in_buf for drawing
            --------
            if i==1 then self.in_buf = tmp_buf.table() else self:table_plus(1, (i-1)*self.full_buf_sz, tmp_buf.table() ) end
            --------
            buf_start = buf_start + self.full_buf_sz/srate -- to next
            ------------------------
        end
        self:Create_Peaks(1)  -- Create_Peaks input(Original) wave peaks
        self.in_buf  = nil    -- входной больше не нужен
    end
    
    -------------------------------------------------------------------------
    -- Filtering >> samples to out_buf >> to table >> create peaks ----------
    -------------------------------------------------------------------------
    local size, n_XBlocks
    local buf_start = self.sel_start
    for i=1, self.n_Full_Bufs+1 do
       if i>self.n_Full_Bufs then size, n_XBlocks = self.rest_buf_sz, self.n_XBlocks_RB 
                             else size, n_XBlocks = self.full_buf_sz, self.n_XBlocks_FB
       end
       ------
       local tmp_buf = r.new_array(size)
       ---------------------------------------------------------
       local block_start = buf_start - (self.crsx/srate)   -- first block in current buf start(regard crsx)   
       for block=1, n_XBlocks do r.GetAudioAccessorSamples(self.AA, srate, 1, block_start, block_size, self.buffer)
           --------------------
           self:Filter_FFT(lowband, hiband)                -- Filter(note: don't use out of range freq!)
           tmp_buf.copy(self.buffer, self.crsx+1, self.Xblock, (block-1)* self.Xblock + 1 ) -- copy block to out_buf with offset
           --------------------
           block_start = block_start + self.Xblock/srate   -- next block start_time
       end
       ---------------------------------------------------------
       if i==1 then self.out_buf = tmp_buf.table() else self:table_plus(2, (i-1)*self.full_buf_sz, tmp_buf.table() ) end
       --------
       buf_start = buf_start + (self.full_buf_sz/srate) -- to next
       ------------------------
    end
    -------------------------------------------------------------------------
    self:Create_Peaks(2)  -- Create_Peaks output(Filtered) wave peaks
    -------------------------------------------------------------------------
    self.State = true -- Change State
    -------------------------
end

Last edited by cool; 03-31-2021 at 07:31 PM.
cool is offline   Reply With Quote
Old 04-01-2021, 12:47 AM   #220
Sicknote
Human being with feelings
 
Join Date: Jun 2017
Posts: 13
Default

hey,

works fantastic. Hope that it isnt a dump question, but how could i save the slices to my harddisk automaticly?
Sicknote is offline   Reply With Quote
Old 04-01-2021, 03:37 AM   #221
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Quote:
Originally Posted by Sicknote View Post
hey,

works fantastic. Hope that it isnt a dump question, but how could i save the slices to my harddisk automaticly?

Hey! This question does not apply to Slicer (at least it does not have such an option), but I will answer it. Just select "Source: Selected Media Items" in the Render settings.
cool is offline   Reply With Quote
Old 04-01-2021, 07:08 AM   #222
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,458
Default

Quote:
Originally Posted by cool View Post
Thanks a lot! Unfortunately, this part of the code (sampling, audio filtering and transient search) was not written by me, and I just have no idea how it works. At the moment, this is too difficult for me to understand.

p.s.
However, I tried it. There were many attempts and I always got either an error or only an error. I could not achieve an increase in performance.

p.p.s.
Here is this part of the code, if I understood everything correctly. I highlighted the line that I took out of the loop. But since self.full_buf_sz is taken inside the loop, I got a predictable error.

The biggest difference in speed will come from the other tip I gave you.. If I find the time I'll see the code and make the changes myself for you
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is offline   Reply With Quote
Old 04-01-2021, 07:59 AM   #223
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Quote:
Originally Posted by amagalma View Post
The biggest difference in speed will come from the other tip I gave you.. If I find the time I'll see the code and make the changes myself for you
Thanks. This would be very helpful.
cool is offline   Reply With Quote
Old 04-01-2021, 08:24 AM   #224
Sicknote
Human being with feelings
 
Join Date: Jun 2017
Posts: 13
Default

thank you very much. maybe it would be a good idea
Sicknote is offline   Reply With Quote
Old 04-20-2021, 05:50 AM   #225
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

v2.12
+ Fixed highlighting of the Grid buttons if the script was launched while the triplet mode was active.
+ The ruler is now more visible.
+ Removed extensive Guides By Grid menu, now the grid is selected with the Grid buttons and is synchronous with the project (experimentally, can be removed).
+ Fixed: the script does not give an error at high sample rates.
cool is offline   Reply With Quote
Old 04-20-2021, 07:07 AM   #226
sinkmusic
Human being with feelings
 
sinkmusic's Avatar
 
Join Date: Feb 2006
Location: decepticon mothership in a hidden place inside a mountain
Posts: 3,754
Default

Thank you !
sinkmusic is offline   Reply With Quote
Old 04-22-2021, 01:10 AM   #227
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Guys, I tried to optimize the speed of the script myself using the advice above, but it seems I broke everything. Please skip version 2.13 (and 2.12, just in case). I will try to return everything as it was in the near future. Sorry for the inconvenience.
cool is offline   Reply With Quote
Old 04-24-2021, 03:22 AM   #228
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

^^It doesn't matter anymore, everything is fixed
v2.14
+ Small optimization of the audio engine (thanks, amagalma!), fixing gross errors of previous versions 2.12 - 2.13.
+ Play Marker is now visible on the Loop Line (useful when working with long items).

I hope these are the last fixes before starting a new script on the same engine. Coming soon. And this is not a Slicer
cool is offline   Reply With Quote
Old 04-24-2021, 07:01 AM   #229
DanSwizer
Human being with feelings
 
DanSwizer's Avatar
 
Join Date: Sep 2019
Posts: 42
Default

Thank you cool! Such a great tool! Why haven't I seen it before?
Is it expected to run a little faster? Now it a bit sluggish on big files.
DanSwizer is offline   Reply With Quote
Old 04-24-2021, 09:17 AM   #230
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Quote:
Originally Posted by DanSwizer View Post
Thank you cool! Such a great tool! Why haven't I seen it before?
Is it expected to run a little faster? Now it a bit sluggish on big files.

You're welcome!

Unfortunately, we have not yet found a way to significantly increase the processing speed. Update 2.14 has a subtle (subtle-subtle) speed boost. It seems that the script is working at the limit of its capabilities, therefore, all recommendations for increasing performance from the first post in this thread remain actual.
cool is offline   Reply With Quote
Old 05-11-2021, 11:04 AM   #231
dsyrock
Human being with feelings
 
dsyrock's Avatar
 
Join Date: Sep 2018
Location: China
Posts: 565
Default

Hi, I have a question about this code, in function get_average_rms:
Code:
-- How many samples are taken from audio accessor and put in the buffer
local samples_per_channel = take_source_sample_rate/10
Why are samples per channel equal to take source sample rate/10?
dsyrock is offline   Reply With Quote
Old 05-12-2021, 12:46 AM   #232
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Hey!

This part of the code only works when the script is run. This is an optimization for coarse RMS computation. This only affects automatic level detection (Filtered Gain slider) on script starts. The precise RMS value is not required here, because this will greatly increase the script launch time.
cool is offline   Reply With Quote
Old 05-14-2021, 12:11 PM   #233
lucafusi
Human being with feelings
 
Join Date: Jul 2016
Posts: 10
Default

Getting an error when trying to load this script today, wasn't there a month or so ago:

Can't load file:

abfx-Scripts\ABFX_Scripts - Set Selected Items Length, Fades, and Pitch to the Same as First Selected Item (Track Independant).lua

I fear my Reapack manager might've removed this while updating this morning and perhaps it was a dependency? Googling that script name doesn't produce any results, sadly.
lucafusi is offline   Reply With Quote
Old 05-14-2021, 06:54 PM   #234
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Quote:
Originally Posted by lucafusi View Post
Getting an error when trying to load this script today, wasn't there a month or so ago:

Can't load file:

abfx-Scripts\ABFX_Scripts - Set Selected Items Length, Fades, and Pitch to the Same as First Selected Item (Track Independant).lua

I fear my Reapack manager might've removed this while updating this morning and perhaps it was a dependency? Googling that script name doesn't produce any results, sadly.

Hmm. This name has nothing to do with my script. My script file is named cool_MK Slicer.lua
cool is offline   Reply With Quote
Old 06-08-2021, 01:33 PM   #235
Anshul999
Human being with feelings
 
Join Date: May 2020
Posts: 41
Default

Hi,
This is an absolutely amazing script. Pretty much revolutionized my life - I can now have almost all my recordings in perfect time haha.
But, my only complaint is that this script is not comfortable using on a laptop trackpad. Can you please add trackpad gestures (perhaps user customizable), since we don't have a middle mouse button and we have horizontal scrolling and multi finger gestures. Some of my suggestions for gestures:

Two-finger horizontal swipe = horizontal scrolling (I use the same action with reaper arrange view as it fits).
Three-finger or four-finger tap = middle mouse button (I can't seem to make this work even though my Windows setting uses four finger tap for middle mouse button).

Actually, just being able to scroll horizontally via touchpad will be the biggest timesaver for me. The 80icio MOD version has this feature, so it is much easier to navigate (but this script is the best for melodic instruments like guitar )

Other than, is there any way for Ctrl + S to work inside the script? I obsessively save my project but it seems it won't work inside the script.

Also, lastly,the sync function doesn't seem to work on script startup. I have to re-enable it to make it work.

Last edited by Anshul999; 06-08-2021 at 01:44 PM.
Anshul999 is offline   Reply With Quote
Old 06-08-2021, 11:27 PM   #236
cool
Human being with feelings
 
Join Date: Dec 2017
Location: Sunny Siberian Islands
Posts: 962
Default

Quote:
Originally Posted by Anshul999 View Post
Hi,
This is an absolutely amazing script. Pretty much revolutionized my life - I can now have almost all my recordings in perfect time haha.
But, my only complaint is that this script is not comfortable using on a laptop trackpad. Can you please add trackpad gestures (perhaps user customizable), since we don't have a middle mouse button and we have horizontal scrolling and multi finger gestures. Some of my suggestions for gestures:

Two-finger horizontal swipe = horizontal scrolling (I use the same action with reaper arrange view as it fits).
Three-finger or four-finger tap = middle mouse button (I can't seem to make this work even though my Windows setting uses four finger tap for middle mouse button).

Actually, just being able to scroll horizontally via touchpad will be the biggest timesaver for me. The 80icio MOD version has this feature, so it is much easier to navigate (but this script is the best for melodic instruments like guitar )

Other than, is there any way for Ctrl + S to work inside the script? I obsessively save my project but it seems it won't work inside the script.

Also, lastly,the sync function doesn't seem to work on script startup. I have to re-enable it to make it work.

Hi.
Horizontal scrolling with the left mouse button was recently added. It duplicates what was previously done with only the middle mouse button. That's all I can do: I don't have a Mac, so I just don't know what features to add and how to test.

Ctrl+S needs to be tested. The idea is good. Perhaps I will add it in the next version of the script.

Synchronization. Now the button status is remembered between script launches. That is, if you disable the Sync button and close the script, the next launch will be with the button disabled. Maybe I should add an option to force it on at startup. I’ll think about it.

Thanks for your feedback and ideas!
cool is offline   Reply With Quote
Old 06-09-2021, 12:03 AM   #237
80icio
Human being with feelings
 
Join Date: Mar 2016
Location: Italy
Posts: 332
Default

Hi Guys!

Left and right swipe gestures on a Mac trackpad are the same as Horizontal wheel on mouse.
If you want to modify the code yourself
Look for function Wave:Get_Mouse() and then add the part between "Mac Osx Trackpad" brackets
hope that helps!

Code:
function Wave:Get_Mouse()
    -----------------------------
local true_position = (gfx.mouse_x-self.x)/Z_w  -- корректировка для захвата краёв waveform
local pos_margin = gfx.mouse_x-self.x
if true_position < 24 then pos_margin = 0 end
if true_position > 1000 then pos_margin = gfx.mouse_x end
self.insrc_mx_zoom = self.Pos + (pos_margin)/(self.Zoom*Z_w) -- its current mouse position in source!

if SnapToStart == 1 then
local true_position = (gfx.mouse_x-self.x)/Z_w  -- корректировка для cursor snap
local pos_margin = gfx.mouse_x-self.x
   if true_position < 12 then pos_margin = 0 end
    self.insrc_mx = self.Pos + (pos_margin)/(self.Zoom*Z_w) 
else
    self.insrc_mx = self.Pos + (gfx.mouse_x-self.x)/(self.Zoom*Z_w) -- old behavior
end

    ----------------------------- 
    --- Wave get-set Cursors ----
    self:Get_Cursor()
    self:Set_Cursor()   
    -----------------------------------------
    --- Wave Zoom(horizontal) ---------------
    if self:mouseIN() and gfx.mouse_wheel~=0 and not(Ctrl or Shift) then 
    local M_Wheel = gfx.mouse_wheel
      -------------------
      if     M_Wheel>0 then self.Zoom = min(self.Zoom*1.25, self.max_Zoom)   
      elseif M_Wheel<0 then self.Zoom = max(self.Zoom*0.75, 1)
      end 
      -- correction Wave Position from src --
      self.Pos = self.insrc_mx_zoom - (gfx.mouse_x-self.x)/(self.Zoom*Z_w)
      self.Pos = max(self.Pos, 0)
      self.Pos = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )
self_Zoom = self.Zoom --refresh loop by mw
      -------------------
      Wave:Redraw() -- redraw after horizontal zoom
    end
    ----------------------------------------- MAC OSX TRACKPAD
     -----------------------------------------
        --- Wave Trackpad move (horizontal) 
        if self:mouseIN() and gfx.mouse_hwheel~=0 then 
        local MH_Wheel = gfx.mouse_hwheel
          -- correction Wave Position from src --
         self.Pos = self.Pos - (MH_Wheel)/(self.Zoom*Z_w)
                    self.Pos = max(self.Pos, 0)
                    self.Pos = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )
                    gfx.mouse_hwheel = 0
          -------------------
          Wave:Redraw() -- redraw after horizontal zoom
        end
        ----------------------------------------- MAC OSX TRACKPAD
    --- Wave Zoom(Vertical) -----------------
    if self:mouseIN() and gfx.mouse_wheel~=0 and (Ctrl or Shift) then 
    local  M_Wheel = gfx.mouse_wheel

------------------------------------------------------------------------------------------------------
     if     M_Wheel>0 then self.vertZoom = min(self.vertZoom*1.2, self.max_vertZoom)   
     elseif M_Wheel<0 then self.vertZoom = max(self.vertZoom*0.8, 1)
     end                 
     -------------------
     Wave:Redraw() -- redraw after vertical zoom
    end
    -----------------------------------------
    --- Wave Move ---------------------------
    if self:mouseM_Down() then 
      self.Pos = self.Pos + (last_x - gfx.mouse_x)/(self.Zoom*Z_w) --gfx.mouse_x
      self.Pos = max(self.Pos, 0)
      self.Pos = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )
      --------------------
self_Zoom = self.Zoom --refresh loop by mw middle click
      Wave:Redraw() -- redraw after move view
    end


    --------------------------------------------
    --- Reset Zoom by Middle Mouse Button------
    if Ctrl and self:mouseM_Down() then 
      self.Pos = 0
      self.Zoom = 1   
      --------------------
    end

              -- loop correction for rng1 and rng2--
      self.Pos3 = self.Pos + (last_x - gfx.mouse_x)/(self.Zoom*Z_w)
      self.Pos3 = max(self.Pos, 0)
      self.Pos3 = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )
      shift_Pos = self.Pos3

     --------------------------------------------------------------------------------
     -- Zoom by Arrow Keys
     --------------------------------------------------------------------------------
local KeyUP
local KeyDWN
local KeyL
local KeyR

    if char==30064 then KeyUP = 1 else KeyUP = 0 end -- up
    if char==1685026670 then KeyDWN = 1 else KeyDWN = 0 end -- down
    if char==1818584692 then KeyL = 1 else KeyL = 0 end -- left
    if char==1919379572 then KeyR = 1 else KeyR = 0 end -- right

-------------------------------horizontal----------------------------------------
     if  KeyR == 1 then self.Zoom = min(self.Zoom*1.2, self.max_vertZoom+138)   

      self.Pos = self.insrc_mx_zoom - (gfx.mouse_x-self.x)/(self.Zoom*Z_w)
      self.Pos = max(self.Pos, 0)
      self.Pos = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )

     Wave:Redraw() -- redraw after horizontal zoom
     else
     end   

     if  KeyL == 1 then self.Zoom = max(self.Zoom*0.8, 1)

      self.Pos = self.insrc_mx_zoom - (gfx.mouse_x-self.x)/(self.Zoom*Z_w)
      self.Pos = max(self.Pos, 0)
      self.Pos = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )

     Wave:Redraw() -- redraw after horizontal zoom
     else
     end   

-------------------------------vertical-------------------------------------------
     if  KeyUP == 1 then self.vertZoom = min(self.vertZoom*1.2, self.max_vertZoom)   
     Wave:Redraw() -- redraw after vertical zoom
     else
     end   

     if  KeyDWN == 1 then self.vertZoom = max(self.vertZoom*0.8, 1)
     Wave:Redraw() -- redraw after vertical zoom
     else
     end   

end
80icio is offline   Reply With Quote
Old 06-09-2021, 08:56 AM   #238
Anshul999
Human being with feelings
 
Join Date: May 2020
Posts: 41
Default

Quote:
Originally Posted by 80icio View Post
Hi Guys!

Left and right swipe gestures on a Mac trackpad are the same as Horizontal wheel on mouse.
If you want to modify the code yourself
Look for function Wave:Get_Mouse() and then add the part between "Mac Osx Trackpad" brackets
hope that helps!

Code:
function Wave:Get_Mouse()
    -----------------------------
local true_position = (gfx.mouse_x-self.x)/Z_w  -- корректировка для захвата краёв waveform
local pos_margin = gfx.mouse_x-self.x
if true_position < 24 then pos_margin = 0 end
if true_position > 1000 then pos_margin = gfx.mouse_x end
self.insrc_mx_zoom = self.Pos + (pos_margin)/(self.Zoom*Z_w) -- its current mouse position in source!

if SnapToStart == 1 then
local true_position = (gfx.mouse_x-self.x)/Z_w  -- корректировка для cursor snap
local pos_margin = gfx.mouse_x-self.x
   if true_position < 12 then pos_margin = 0 end
    self.insrc_mx = self.Pos + (pos_margin)/(self.Zoom*Z_w) 
else
    self.insrc_mx = self.Pos + (gfx.mouse_x-self.x)/(self.Zoom*Z_w) -- old behavior
end

    ----------------------------- 
    --- Wave get-set Cursors ----
    self:Get_Cursor()
    self:Set_Cursor()   
    -----------------------------------------
    --- Wave Zoom(horizontal) ---------------
    if self:mouseIN() and gfx.mouse_wheel~=0 and not(Ctrl or Shift) then 
    local M_Wheel = gfx.mouse_wheel
      -------------------
      if     M_Wheel>0 then self.Zoom = min(self.Zoom*1.25, self.max_Zoom)   
      elseif M_Wheel<0 then self.Zoom = max(self.Zoom*0.75, 1)
      end 
      -- correction Wave Position from src --
      self.Pos = self.insrc_mx_zoom - (gfx.mouse_x-self.x)/(self.Zoom*Z_w)
      self.Pos = max(self.Pos, 0)
      self.Pos = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )
self_Zoom = self.Zoom --refresh loop by mw
      -------------------
      Wave:Redraw() -- redraw after horizontal zoom
    end
    ----------------------------------------- MAC OSX TRACKPAD
     -----------------------------------------
        --- Wave Trackpad move (horizontal) 
        if self:mouseIN() and gfx.mouse_hwheel~=0 then 
        local MH_Wheel = gfx.mouse_hwheel
          -- correction Wave Position from src --
         self.Pos = self.Pos - (MH_Wheel)/(self.Zoom*Z_w)
                    self.Pos = max(self.Pos, 0)
                    self.Pos = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )
                    gfx.mouse_hwheel = 0
          -------------------
          Wave:Redraw() -- redraw after horizontal zoom
        end
        ----------------------------------------- MAC OSX TRACKPAD
    --- Wave Zoom(Vertical) -----------------
    if self:mouseIN() and gfx.mouse_wheel~=0 and (Ctrl or Shift) then 
    local  M_Wheel = gfx.mouse_wheel

------------------------------------------------------------------------------------------------------
     if     M_Wheel>0 then self.vertZoom = min(self.vertZoom*1.2, self.max_vertZoom)   
     elseif M_Wheel<0 then self.vertZoom = max(self.vertZoom*0.8, 1)
     end                 
     -------------------
     Wave:Redraw() -- redraw after vertical zoom
    end
    -----------------------------------------
    --- Wave Move ---------------------------
    if self:mouseM_Down() then 
      self.Pos = self.Pos + (last_x - gfx.mouse_x)/(self.Zoom*Z_w) --gfx.mouse_x
      self.Pos = max(self.Pos, 0)
      self.Pos = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )
      --------------------
self_Zoom = self.Zoom --refresh loop by mw middle click
      Wave:Redraw() -- redraw after move view
    end


    --------------------------------------------
    --- Reset Zoom by Middle Mouse Button------
    if Ctrl and self:mouseM_Down() then 
      self.Pos = 0
      self.Zoom = 1   
      --------------------
    end

              -- loop correction for rng1 and rng2--
      self.Pos3 = self.Pos + (last_x - gfx.mouse_x)/(self.Zoom*Z_w)
      self.Pos3 = max(self.Pos, 0)
      self.Pos3 = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )
      shift_Pos = self.Pos3

     --------------------------------------------------------------------------------
     -- Zoom by Arrow Keys
     --------------------------------------------------------------------------------
local KeyUP
local KeyDWN
local KeyL
local KeyR

    if char==30064 then KeyUP = 1 else KeyUP = 0 end -- up
    if char==1685026670 then KeyDWN = 1 else KeyDWN = 0 end -- down
    if char==1818584692 then KeyL = 1 else KeyL = 0 end -- left
    if char==1919379572 then KeyR = 1 else KeyR = 0 end -- right

-------------------------------horizontal----------------------------------------
     if  KeyR == 1 then self.Zoom = min(self.Zoom*1.2, self.max_vertZoom+138)   

      self.Pos = self.insrc_mx_zoom - (gfx.mouse_x-self.x)/(self.Zoom*Z_w)
      self.Pos = max(self.Pos, 0)
      self.Pos = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )

     Wave:Redraw() -- redraw after horizontal zoom
     else
     end   

     if  KeyL == 1 then self.Zoom = max(self.Zoom*0.8, 1)

      self.Pos = self.insrc_mx_zoom - (gfx.mouse_x-self.x)/(self.Zoom*Z_w)
      self.Pos = max(self.Pos, 0)
      self.Pos = min(self.Pos, (self.w - self.w/self.Zoom)/Z_w )

     Wave:Redraw() -- redraw after horizontal zoom
     else
     end   

-------------------------------vertical-------------------------------------------
     if  KeyUP == 1 then self.vertZoom = min(self.vertZoom*1.2, self.max_vertZoom)   
     Wave:Redraw() -- redraw after vertical zoom
     else
     end   

     if  KeyDWN == 1 then self.vertZoom = max(self.vertZoom*0.8, 1)
     Wave:Redraw() -- redraw after vertical zoom
     else
     end   

end
Thank you so much! This works perfectly now on Windows 10. Is there any way to reverse the direction of the horizontal scrolling though? I am used to reversed scrolling, and now MKSlicer and the Reaper Arrange view scroll in opposite directions. I'm a complete noob at coding, so I couldn't make sense of what was required to be changed.
Anshul999 is offline   Reply With Quote
Old 06-09-2021, 10:10 AM   #239
80icio
Human being with feelings
 
Join Date: Mar 2016
Location: Italy
Posts: 332
Default

Quote:
Originally Posted by Anshul999 View Post
Thank you so much! This works perfectly now on Windows 10. Is there any way to reverse the direction of the horizontal scrolling though? I am used to reversed scrolling, and now MKSlicer and the Reaper Arrange view scroll in opposite directions. I'm a complete noob at coding, so I couldn't make sense of what was required to be changed.
I think you should just change this line
Code:
self.Pos = self.Pos - (MH_Wheel)/(self.Zoom*Z_w)
to

Code:
self.Pos = self.Pos + (MH_Wheel)/(self.Zoom*Z_w)
let me know if that works
80icio is offline   Reply With Quote
Old 06-09-2021, 12:55 PM   #240
Anshul999
Human being with feelings
 
Join Date: May 2020
Posts: 41
Default

Quote:
Originally Posted by 80icio View Post
I think you should just change this line
Code:
self.Pos = self.Pos - (MH_Wheel)/(self.Zoom*Z_w)
to

Code:
self.Pos = self.Pos + (MH_Wheel)/(self.Zoom*Z_w)
let me know if that works
Works perfectly now! Thank you so much!
Anshul999 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 10:33 PM.


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