Old 02-24-2017, 07:02 PM   #1
eugen2777
Human being with feelings
 
eugen2777's Avatar
 
Join Date: Aug 2012
Posts: 271
Default Lua: New Function - GetMediaItemTake_Peaks

We are now able to use this?
It definitely will not be changed?
=============
Example:
Code:
min_freq = 80
max_freq = 1000
Thresh_dB = -40
min_tonal = 0.85

------------------------------------------------------------
function Init()
    -- Some gfx Wnd Default Values ---------------
    local Wnd_bgd = 0x0F0F0F  
    local Wnd_Title = "Test"
    local Wnd_Dock,Wnd_X,Wnd_Y = 0,100,320 
    Wnd_W,Wnd_H = 1044,490 -- global values(used for define zoom level)
    -- Init window ------
    gfx.clear = Wnd_bgd         
    gfx.init( Wnd_Title, Wnd_W,Wnd_H, Wnd_Dock, Wnd_X,Wnd_Y )  
end

------------------------------------------------------------
function Peaks_Draw(Peaks)
  local min_note = 69 + 12 * math.log(min_freq/440, 2)
  local max_note = 69 + 12 * math.log(max_freq/440, 2)
  local Thresh = 10 ^ (Thresh_dB/20)
  ----------------------
  local axis = gfx.h * 0.5
  local Ky = gfx.h * 0.5
  local Kn = gfx.h/(max_note-min_note)
  local offs = min_note * Kn
  ----------------------
  local abs, max = math.abs, math.max
  for i = 1, #Peaks, 4 do
    local max_peak, min_peak = Peaks[i], Peaks[i+1]
    local xx = i/4
    gfx.set(0,0.5,0,1)
    gfx.line(xx , axis - max_peak*Ky, xx, axis - min_peak*Ky, true) -- Peaks   
    -------------------- 
    if max(abs(max_peak), abs(min_peak)) > Thresh then
      local freq, tonal = Peaks[i+2], Peaks[i+3]
      local note = 69 + 12 * math.log(freq/440, 2)  
      if tonal >= min_tonal and note >= min_note and note <= max_note then
        gfx.x = xx; gfx.y = gfx.h + offs - note*Kn;
        gfx.setpixel(1,0,0)
      elseif note < min_note then
        gfx.x = xx; gfx.y = gfx.h - 10;
        gfx.setpixel(0,0,1)
      elseif note > max_note then
        gfx.x = xx; gfx.y = 10;
        gfx.setpixel(0,1,1)
      end
    end
  end
   
end
------------------------------------------------------------
function Item_GetPeaks(item)
  if not item then return end
  local take = reaper.GetActiveTake(item)
  if not take or reaper.TakeIsMIDI(take) then return end
  local item_start = reaper.GetMediaItemInfo_Value(item, "D_POSITION")
  local item_len = reaper.GetMediaItemInfo_Value(item, "D_LENGTH")
  local sel_start, sel_end = reaper.GetSet_LoopTimeRange(false, false, 0, 0, false)
  if sel_end - sel_start == 0 then sel_start = item_start; sel_end = item_start + item_len end
  
  local starttime = math.max(sel_start, item_start)
  local len = math.min(sel_end, item_start + item_len) - starttime
  if len <= 0 then return end 
  ------------------
  --PCM_Source = reaper.GetMediaItemTake_Source(take)
  local n_chans = 1   -- I GetPeaks Only from 1 channel!!!
  local peakrate = gfx.w / len
  local n_spls = math.floor(len*peakrate + 0.5) -- its Peak Samples         
  local want_extra_type = 115  -- 's' char
  local buf = reaper.new_array(n_spls * n_chans * 3) -- max, min, spectral each chan(but now 1 chan only)
  buf.clear()         -- Clear buffer
  ------------------
  local retval = reaper.GetMediaItemTake_Peaks(take, peakrate, starttime, n_chans, n_spls, want_extra_type, buf);
  local spl_cnt  = (retval & 0xfffff)        -- sample_count
  local ext_type = (retval & 0x1000000)>>24  -- extra_type was available
  local out_mode = (retval & 0xf00000)>>20   -- output_mode
  ------------------
  local Peaks = {}
  if spl_cnt > 0 and ext_type > 0 then
    for i = 1, n_spls do
      local p = #Peaks
      Peaks[p+1] = buf[i]             -- max peak
      Peaks[p+2] = buf[n_spls + i]    -- min peak
      --------------
      local spectral = buf[n_spls*2 + i]    -- spectral peak
      -- freq and tonality from spectral peak --
      Peaks[p+3] = spectral&0x7fff       -- low 15 bits frequency
      Peaks[p+4] = (spectral>>15)/16384  -- tonality norm value 
    end
  end
  ------------------
  return Peaks
end

---------------------------
function Project_IsChanged()
    local cur_cnt = reaper.GetProjectStateChangeCount(0)
    if cur_cnt ~= proj_change_cnt then proj_change_cnt = cur_cnt
       return true  
    end
end

---------------------------
function main()    
    if Project_IsChanged() then
      gfx.setimgdim(0, 0, 0) -- clear buf 0
      gfx.setimgdim(0, gfx.w, gfx.h)
      gfx.dest = 0; -- set dest buf = 0   
      local item = reaper.GetSelectedMediaItem(0, 0) 
      if item then
        local Peaks = Item_GetPeaks(item) 
        if Peaks then Peaks_Draw(Peaks) end
      end 
    end
    -----------
    local img_w, img_h = gfx.getimgdim(0)
    if img_w > 0 and img_h > 0 then
      gfx.a = 1; gfx.dest = -1; gfx.x, gfx.y = 0, 0
      gfx.blit(image, 1, 0, 0, 0, img_w, img_h, 0, 0, gfx.w, gfx.h)
    end
    ----------- 
    char = gfx.getchar() 
    if char == 32 then reaper.Main_OnCommand(40044, 0) end -- play
    if char ~= -1 then reaper.defer(main) end              -- defer       
    -----------  
    gfx.update()
    -----------
end

Init()
main()
__________________
ReaScripts

Last edited by eugen2777; 11-08-2017 at 10:12 AM.
eugen2777 is offline   Reply With Quote
Old 02-25-2017, 07:39 AM   #2
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 4,689
Default

Hi eugen,sorry for offtopic but you got something I really need for a long time. I've modified the script a little to act the way I need but:

How can I draw edit cursor here so it replicates the position from arrange?

I need this "Editing Guide" when editing tracks that are bellow or in the middle of the project and I cannot see the source track. The script needs to "Lock Waveform of selected track" so here is a little gif.

Lets say I've locked the first track "Kick" as GUIDE track, now that waveform stays in the script so I can see it as I edit another track. But I need edit cursor position also to be drawed so I know how much I need to offset the new edit. Hope this makes sence.


Now I only need to see edit cursor too in the script


In your script I only modified the start-end to be arrange window rather than time selection
Code:
sel_start, sel_end = reaper.BR_GetArrangeView(0)
I did not included or coded Lock track yet

Here is the mockup what I need :


Thank you very much!

Last edited by Sexan; 02-25-2017 at 07:50 AM.
Sexan is offline   Reply With Quote
Old 02-26-2017, 07:18 AM   #3
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 4,689
Default

It can be EXTREMELY efficient when optimized even at much higher resolutions by dinamically altering it based on zoom level
Sexan is offline   Reply With Quote
Old 02-26-2017, 10:10 AM   #4
eugen2777
Human being with feelings
 
eugen2777's Avatar
 
Join Date: Aug 2012
Posts: 271
Default

Yes, it is very fast, it was just a simple example.
Specifically, as to make it easier.
And do not forget, pay attention to the frequency of the, it's more fun
__________________
ReaScripts
eugen2777 is offline   Reply With Quote
Old 02-26-2017, 10:28 AM   #5
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 4,689
Default

Sorry for writing off topic here,this is the first simple script for waveforms so I've finally learned something about it, thank you very much!

I've removed "not-necessary" code from it to adjust it to my needs (a very very simple waveform viewer),but I have one issue that I do not know yet how to fix

https://dl.dropboxusercontent.com/u/...dification.lua

At the end of the item weird jiterring begins :

I assume its because there are no more samples at the end so it freaks out like this

And please can you show me how to draw edit cursor in the script (never done that before)?

Once again thank you very much!

Quote:
Originally Posted by eugen2777 View Post
And do not forget, pay attention to the frequency of the, it's more fun
I think I've removed that from the code if you mean "frequency = spec&0x7fff"
Sexan is offline   Reply With Quote
Old 02-26-2017, 12:38 PM   #6
eugen2777
Human being with feelings
 
eugen2777's Avatar
 
Join Date: Aug 2012
Posts: 271
Default

Well, I'll look at it tomorrow, I have no time now!
This will be decided!
__________________
ReaScripts
eugen2777 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 01:51 AM.


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