Old 06-13-2018, 09:53 PM   #1
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
Default PCM_Source_GetPeaks can anyone check?

Code:
  
  function GetPeaks(take, conf)
    if not take then return end
    local peakrate = conf.WF_peaks_resolution or 5000
    local src = GetMediaItemTake_Source( take )
      if not src then return end
      local src_len =  GetMediaSourceLength( src )
      local n_spls = math.floor(src_len*peakrate)
      if n_spls < 10 then return end 
      local n_ch = 1
      local want_extra_type = 115  -- 's' char
      local arr_sz = n_spls * n_ch * 3
      local buf = new_array(arr_sz)
        -------------
      local retval =  PCM_Source_GetPeaks(    src, 
                                        peakrate, 
                                        0,--starttime, 
                                        n_ch,--numchannels, 
                                        n_spls, 
                                        want_extra_type, 
                                        buf )
      local spl_cnt  = (retval & 0xfffff)
      peaks = {}      
      local id = 0
      local arr_s_sz = math.floor(arr_sz/3)
      for i=1, arr_s_sz,2 do  
        id = id + 1 
        peaks[id] = {val = buf[i],
                     pitch = buf[i+arr_s_sz*2],
                     pos = i * src_len / spl_cnt}
      end
      buf.clear()
      return peaks, src_len
  end
I try to build table which return value, pitch and position from (spectral) peaks. Am I doing this right? Not sure about minimum/maximum thing and pitch integers is MIDI pitch right?
mpl is offline   Reply With Quote
Old 06-14-2018, 05:19 AM   #2
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@mpl
EEL will be far more efficient from this ! I tried it :P



here is my EEL function for get pitch:


Code:
function GetPitch(take, nch, pos) local(ns, rv, spl, tonality, pitch, buf)(
  ns = 1;
  buf = 1000;
  tonality = 0;
  rv = GetMediaItemTake_Peaks(take,1000.0, pos,nch,ns,115,buf);
  rv & (1<<24) && (rv&0xfffff) > 0 ? (
    spl = buf[nch*ns*2];
    pitch = spl&0x7fff;
    tonality = (spl>>15)/16384.0;
  );
  pitch;
);
X-Raym is offline   Reply With Quote
Old 06-14-2018, 07:55 AM   #3
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
Default

Thanks! I`m so addicted to lua and almost forget EEL synthax (I know about EEL efficiency for stuff like that).
Can you explain me what are tonality and pitch here? Ok pitch is 1-127 I guess, what is tonality? I trying to find more quick way to get RMS envelope and pitch envelope for AlignTakes2 so I`ll be able not only aligh timing but also slightly modify pitch.
mpl is offline   Reply With Quote
Old 06-14-2018, 08:11 AM   #4
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Hmmmm dont remember lol. And the fact that the value isn't returned means it is probably useless ^^ I think one was 1-127 and the other was Hertz value, but I only needed one.
I think hz is pitch.


It was very confusing functions to set up right I should have put more comment.


Quote:
I`m so addicted to lua and almost forget EEL synthax
Fore sure, Lua syntax is way more flexible !


But performance is key in such things, we are talking about an increase of x10, so it feels like a native function !


You can still use Lua for protoyping, and EEL for end results.


Though, building GUI in EEL isn't easy, and start from an existing already very compelx stuffs, so just according to time dev needed to port EEL... stay in Lua ^^
X-Raym is offline   Reply With Quote
Old 06-14-2018, 03:20 PM   #5
eugen2777
Human being with feelings
 
eugen2777's Avatar
 
Join Date: Aug 2012
Posts: 271
Default

mpl
Some info in this tread - #23 - 24.

Min-max peak-samples contain information information about the minimum and maximum for this peak time range. It can be used for drawing waveform and some other.

Extra peaks as far as I understand, have some information about the prevailing frequency (based on the fft ???).
This is not a tone detector!) - but you can use it for certain situations.

Example
https://stash.reaper.fm/33751/GetTakePeaks111.png

================================================== =
Короче, на русском могу объяснить гораздо проще и понятнее... и подробнее.
Сразу говорю - все примеры, названия для простоты! peak sample - назову просто пик.
К примеру, мы имеем 10 секунд сигнала с семплрейтом = 44100.
Разобьем на 1000 частей. На каждую часть прийдется (44100 * 10) / 1000 = 441 значение.
Для каждой из 1000 частей из 441 значения найдем максимум и минимум.
Это и есть те самые "maximums, minimums".

Использую их можно отобразить форму волны(недопилено - https://forum.cockos.com/showthread.php?t=175701&page=2)
Свой пример опять вставил не из забавы, дело в другом - он на Lua, и туда в легкую час аудио грузится, зумится, перематывается во все стороны практически незаметно. Ф-я работает очень быстро и в Lua, если цеплять блоками. Функция ведь на блоки, в основном и рассчитана. Цеплять один пик, следом другой и тд это.... не то, очень мягко говоря.
Еще момент по параметрам - в примере с отрисовкой, допустим, всегда нужно кол-во блоков, соответ. ширине экрана, что на час аудио, что на 5 сек.
То есть там подстраивать нужно peakrate. Это наиболее выгодно, плюс удобно потом все считать.
Но функцию также можно использовать и для всяких других задач, вопрос фантазии.
--------------
По поводу extra :
побитовое "&" - extra & 0x7fff - это дает младшие 15 бит - частоту.
битовый сдиг ">>" - extra >> 15 - дает следующие 14 бит - tonality.
14-битное целое число может принимать значения - 0 ... 16383, всего 16384.
(extra >> 15) / 16384 - дает нормализованное значение - 0 ... 1.

Частота - по моим тестам - это преобладающая на соответствующем конкретному пику участке времени частота, надо еще проверить.
tonality - насколько понял из поста Джастина - нечто типа "веса". Это похоже на макс. бин и fft - только предположение.
И по тестом что-то подобное... То есть, частота таким методом легко находится когда сигнал простой и не оч. низкий.
Но, по памяти - там есть опр. разрешение по времени вроде. И по нотам на низких - там разрешение в 1 герц - это дохрена - понятно и так.


peakrate - частота, отбора пиков - чем выше, тем меньше семплов приходится на один пик. когда peakrate = srate на 1 пик приходится один семпл.
starttime - врем. позиция, с которой берется блок пиков.
numchannels - это ясно
numsamplesperchannel - кол-во пиков, размер того тот самого блока
want_extra_type - расписано в док.
reaper.array buf - массив для пиков. Его длину нужно посчитать исходя из пред. параметров.

В массиве по итогу будет несколько "частей" - пример для двух каналов.
maximums,
1Lmax
1Rmax
2Lmax
2Rmax
...
NLmax
NRmax
=======
minimums,
1Lmin
1Rmin
2Lmin
2Rmin
...
NLmin
NRmin
=======
extra(если указано в параметрах)
1ext
2ext
__________________
ReaScripts

Last edited by eugen2777; 06-14-2018 at 07:57 PM.
eugen2777 is offline   Reply With Quote
Old 06-14-2018, 04:36 PM   #6
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
Default

Ah so tonality is the "power" of found central frequency, so it can be used as a detection threshold. That make sense.
Thanks, I finally got it to work.




which piece looks like this
Code:
      for i=spl_start, spl_end do
        id = id + 1 
        local spectr_data = math.floor(buf[i+spl_cnt*2])
        local pos = i * spl_len
        local freq = spectr_data&0x7fff
        local tonality = (spectr_data>>15)/16384
        local MIDIpitch = 69 + 12*math.log(freq/440)
        if tonality < 0.6 or buf[i] < 0.005 then MIDIpitch = 0 end
        peaks[id] = { val = buf[i],
                      pos = pos,
                      MIDIpitch = MIDIpitch}
      end
I would say it IS a tone detector, it just use simple algorythm based on spectral power (so the results are pretty rough, although more than enough for spectral peaks without increasing CPU usage). But having more advanced stuff like comb-filtering+autocorrelation detection function would be nice.

Last edited by mpl; 06-14-2018 at 05:29 PM.
mpl is offline   Reply With Quote
Old 06-14-2018, 07:54 PM   #7
eugen2777
Human being with feelings
 
eugen2777's Avatar
 
Join Date: Aug 2012
Posts: 271
Default

Added information to the message, but in Russian
I was making a topic and a piece of code(only micro-test), there's something like your code. Oh, I thought you saw ...
Ok. You can also use min-max freq, peaks min-max for silence - threshold etc.
Использовать эту ф-ю можно, ее возможности, но понадобятся и доп. вещи....хз.
__________________
ReaScripts

Last edited by eugen2777; 06-14-2018 at 08:53 PM.
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 12:06 PM.


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