Prev Previous Post   Next Post Next
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
 

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.