ReaScripts (скрипты для Reaper) - Учимся создавать!!!

@Archchie, как вариант
forum.cockos.com/archive/index.php/t-168270.html
но было бы неплохо узнать есть ли удобнее)
 
  • Like
Реакции: Archie's
PHP:
defer_rate = 1

cycle = 0
function mainloop ()
  cycle = cycle+1
  if cycle == defer_rate then
    main()
    cycle = 0
  end

  if TEST_Env then
    char = gfx.getchar()
    if char~=-1 then reaper.defer(mainloop) end --defer
    gfx.update() -- Update gfx window
  else
    reaper.defer(mainloop)
  end
end
 
  • Like
Реакции: Archie's
Это вырванно из скрипта и не есть универсальной функцией, но смысл понятен -
Дефер запускает по циклу промежуточную функцию - счетчик, и можно, задавая defer_rate, менять скорость перезапуска функции main()
 
Код:
if gfx.getchar() >= 0 and gfx.getchar() ~= 27 then reaper.defer(СКРИПТ) else reaper.atexit(gfx.quit) end
Спасибо, @@Michael, только он (дефер) все равно работает вроде...
Я поставил консоль для теста: оно закрывается, а в консоли продолжают изменятся значения, даже если закрыть проект и открыть новый
 
Последнее редактирование:
Ребята, а можно как-то удалить точку автоматизации ссылаясь на ее номер?
И еще как можно функционально узнать в каких единицах измеряется данный трек автоматизации (к примеру верхняя и нижняя точки)
 
Последнее редактирование:
Ребята, а можно как-то удалить точку автоматизации ссылаясь на ее номер?
Можно.
Узнать её time и удалить по PointRange.
И еще как можно функционально узнать в каких единицах измеряется данный трек автоматизации (к примеру верхняя и нижняя точки)
А оно всегда от 0 до 1, на сколько помню.
 
@Aleksandr Oleynik, ну это по времени, это я умею.. Мне нужно по номеру))

Про автоматизацию, то я немного поколупался, нашел как узнать крайние значения и уже думал, что сделал то, что нужно, но набрел на кучу подводных камней, которые сложно контролировать:
Там есть много вариантов от 0 до 1 это наверное только стандартные, а ля громкость и тп... И при том что соотношение редактируемых параметров другое: громкость в дБ, от бесконечности до 0 (смотря как в настройках), панораме тоже заморочки от 100Л до 100Р, и это все в коде регулируется от 0 до 1... Единственное что мьютирование легко реализируется=))

В РеаконтролМИДИ уже другая систем - либо в тисячах либо как велосити от 0 до 127 (если в настройках РеаконтролМиди поменять), а если не поменять то будет тысячами как питч (из того же РеаконтролМиди)...

Внешние плагины в зависимости от параметра автоматизируемой ручки
Одним словом жуть...
 
Привет, ребята! Можно как-то отследить уровень дБ на аудио айтеме?
Задача удалить хвост (только хвост) когда он нижу определенного уровня (к примеру -24 дБ)
Стандартный удалятель тишины не сильно подходит, т.к. он показывает оно, да и еще некоторые штучки есть
 
@Rsay, Первое что пришло в голову fade-in, fade-out. Когда приходит "ОНО", со своими ШТУЧКАМИ, я НИЖУ плинтуса сразу, трешхолдит не по децки (минус 24 дБ минимум).
 
Привет, ребята! Можно как-то отследить уровень дБ на аудио айтеме?
Задача удалить хвост (только хвост) когда он нижу определенного уровня (к примеру -24 дБ)
Стандартный удалятель тишины не сильно подходит, т.к. он показывает оно, да и еще некоторые штучки есть
Можно, но задачка не из тривиальных.
Женя мне делал Функцию, которая складывала точки в которых уровень сигнала в айтеме ниже заданного и выше заданного.
Очень не просто её даже вычленить из моего скрипта для другой задачи.

А так то -
GetMediaItemTake_Peaks
а дальше - мрак

Вот часть кода формирующего таблицы -
PHP:
attThresh_dB = -65  -- уровень Wav кривой выше которого скрипт включает Fx OnOff
relThresh_dB = -60  -- уровень Wav кривой ниже которого скрипт выключает Fx OnOff

function GetAudioItemTrigPoints(item)
  local take = reaper.GetActiveTake(item)
  take = reaper.GetActiveTake(item)
  if not take then return {}   -- пока пустая таблица
  elseif reaper.TakeIsMIDI(take) then return GetMIDIItemTrigPoints(item, take)
  end
  local item_start = reaper.GetMediaItemInfo_Value(item, "D_POSITION")
  local item_len = reaper.GetMediaItemInfo_Value(item, "D_LENGTH")
  ------------------
  local starttime, n_chans, n_spls, want_extra_type, buf, retval
  n_chans = 1         -- GetPeaks only 1 channel now!!!
  n_spls = math.ceil(item_len*peakrate) -- Note: its Peak Samples!
  want_extra_type = 0 -- get min, max, no spectral
  buf = reaper.new_array(n_spls * n_chans * 2) -- max, min, only for 1 channel
  buf.clear()         -- Clear buffer
  retval = reaper.GetMediaItemTake_Peaks(take, peakrate, item_start, n_chans, n_spls, want_extra_type, buf)
  ------------------
  local attThresh  = 10^(attThresh_dB/20)
  local relThresh  = 10^(relThresh_dB/20)
  local trig_points = {}
  local last_trig = false
  for i = 1, n_spls do
    local max_peak = math.max(math.abs(buf[i]), math.abs(buf[i+n_spls]))
    if not last_trig and max_peak >= attThresh then
      trig_points[#trig_points+1] = {item_start + (i-1)/peakrate, true}; last_trig = true
    elseif last_trig and max_peak < relThresh then
      trig_points[#trig_points+1] = {item_start + (i-1)/peakrate, false}; last_trig = false
    end
  end
  ------------------
  if #trig_points > 0 then
    if trig_points[1][2] ~= false then  -- Start всегда false, начало айтема
      table.insert(trig_points, 1, {item_start, false})
    end
    if trig_points[#trig_points][2] ~= false then  -- End всегда false, конец айтема
      table.insert(trig_points, {item_start + item_len, false})
    end
  end
  ------------------
  return trig_points
end

local items_trig = {} -- Таблица триг. точек для айтемов
  local item_cnt = reaper.CountTrackMediaItems(track)
  for i = 1, item_cnt do
    local item = reaper.GetTrackMediaItem(track, i-1)
    items_trig[i] = GetAudioItemTrigPoints(item)
  end
 
Последнее редактирование:
Подскажите пожалуйста как создать код что бы железно было без анду точки? Потому когда настройки такие



он создает кучу точек. Код сделал как учили, но чего то не помогает
Код стоит на клике мышкой

Код:
function click()
reaper.PreventUIRefresh(1)

reaper.Main_OnCommand(40635, 0) ---Time selection: Remove time selection

reaper.Main_OnCommand(reaper.NamedCommandLookup('_SWS_UNSELALL'), 0) ----SWS: Unselect all items/tracks/env points


reaper.Main_OnCommand(40513, 0)--View: Move edit cursor to mouse cursor

reaper.PreventUIRefresh(-1)

end

reaper.defer(click)
 
@incubator,
С одной Undo точкой
PHP:
function click()

    reaper.Undo_BeginBlock()
    reaper.PreventUIRefresh(1)

    reaper.Main_OnCommand(40635, 0) ---Time selection: Remove time selection

    reaper.Main_OnCommand(reaper.NamedCommandLookup('_SWS_UNSELALL'), 0) ----SWS: Unselect all items/tracks/env points

    reaper.Main_OnCommand(40513, 0)--View: Move edit cursor to mouse cursor

    reaper.PreventUIRefresh(-1)
    reaper.Undo_EndBlock("name_script",1)

end
click()

Без Undo точек: / Deselect All 'move play cursor under mouse cursor[no undo]
PHP:
    -----------------------------------------------------------------------------
    local function No_Undo()end; local function no_undo()reaper.defer(No_Undo)end
    -----------------------------------------------------------------------------


    reaper.GetSet_LoopTimeRange( 1, 0, 0, 0, 0 )

    local window, segment, details = reaper.BR_GetMouseCursorContext()
    local mouse = reaper.BR_GetMouseCursorContext_Position()
    if mouse > 0 then
        reaper.SetEditCurPos( mouse , 0, 0 )
    end

    local count_track = reaper.CountTracks()
    if count_track == 0 then
         no_undo()
       return
    end


    reaper.PreventUIRefresh(1)

    for i = 1,count_track do

        local tr = reaper.GetTrack(0,i-1)
        reaper.SetTrackSelected( tr, 0 )
  
        local count_tr_item = reaper.CountTrackMediaItems( tr )
        for i2 = 1,count_tr_item do
            local tr_item = reaper.GetTrackMediaItem( tr, i2-1 )
            reaper.SetMediaItemSelected( tr_item, 0 )
        end
        local count_track_env =  reaper.CountTrackEnvelopes( tr )
        for i2 = 1,count_track_env do
            local track_env = reaper.GetTrackEnvelope( tr , i2-1 )
            local count_Env_Point = reaper.CountEnvelopePoints( track_env )
            for i3 = 1,count_Env_Point do
                reaper.SetEnvelopePoint( track_env, i3-1, _, _, _, _, 0, _ )
            end
            local count_automat_item = reaper.CountAutomationItems( track_env )
            for i3 = 1,count_automat_item do
                reaper.GetSetAutomationItemInfo( track_env, i3-1, 'D_UISEL', 0, 1 )
            end
        end
    end

    reaper.PreventUIRefresh(-1)
    reaper.UpdateArrange()
    no_undo()
 
Последнее редактирование:
@Aleksandr Oleynik, пришлось научится удалять лишнее в хвоте с помощью удалятеля тишины, но это пока так себе вариант, не во всех случаях что мне надо работает, да и окно выскакивает и настройки менять не особо можно
 
@@Michael, как тримить айтем (левый, правый его край)?
Что то по простому только через экшины нашёл. Может есть и в API?

Ни это ?
reaper.ApplyNudge( project, nudgeflag, nudgewhat, nudgeunits, value, reverse, copies )
-- только эта функция работает для всех выделенных айтемов

или
обновил 2-й раз 16.05.18.
Предыдущая не правильно работала с растянутым play-rate:
PHP:
правый край

reaper.SetMediaItemLength( item, length, true )

---------------------------------------------------------

левый край

  local function SetMediaItemLeftTrim(value,item)
    local Pos = reaper.GetMediaItemInfo_Value( item, 'D_POSITION' )
    local len = reaper.GetMediaItemInfo_Value( item, 'D_LENGTH' )
    local take = reaper.GetActiveTake( item )
    local playrate = reaper.GetMediaItemTakeInfo_Value( take, 'D_PLAYRATE')
    local offset = reaper.GetMediaItemTakeInfo_Value( take, 'D_STARTOFFS' )
    if len > value then
      reaper.SetMediaItemLength( item,  value , true )
      reaper.SetMediaItemPosition( item,(len-value)+ Pos, true )
      reaper.SetMediaItemTakeInfo_Value( take, 'D_STARTOFFS',offset + (len-value)*playrate )
    else
      if Pos < (value-len) then return end
      reaper.SetMediaItemLength( item, value , true )
      reaper.SetMediaItemPosition( item, Pos-(value-len), true )
      reaper.SetMediaItemTakeInfo_Value( take, 'D_STARTOFFS',offset + (len-value)*playrate )
    end
  end
 
Последнее редактирование:
  • Like
Реакции: Aleksandr Oleynik
А никто не знает, где поискать алгоритм для поиска loop points?
Я тут пытаюсь немного автоматизировать процес нарезки сэмплов. И самый ад, конечно, происходит при нарезке сустейнов.
В общем и целом концепция очень простая:
  • вычленяем "чистый" фрагмент сустейна (это лучше делать "человеком")
  • режем в произвольной точке
  • меняем местами начало и конец
  • и делаем так.
2018-05-25_03-24-40.png


Но если сделать "просто" так, в лучшем случае будет тембральный, и, наверняка, динамический контраст.
А в худшем, и это не редкость, а, скорее, очень частая напасть, попадаешь в противофазу, да так, что найти фазу, в силу "живости" источника - та еще задачка.

Вот идеально с этой задачей, КМК, справляется sample robot. Но он, к сожалению, работает только на стерео, что в нашу много-микрофонную бытность не комильфо.
Гуглинг засран простыми howto для обыкновенных лупов (драмсы, гитарные рифы), а найти что-то стоящее по закольцовке сэмплов я чет не могу.

Набрел на такую тему https://forum.cockos.com/showthread.php?t=180087

Но, во-первых, это слишком жирно, учитывая 6+ исходных треков для каждого сэмпла. А во-вторых, мне кажется, кардинально от моего способа это дело не отличается, все равно точно также можно нарваться на противофазу.
Есть идеи?
 
попробовал начать с самого очевидного: поиска одинаковых сэмплов в тейке:
Код:
def find_loop(take, search_area):
    accessor = RPR_CreateTakeAudioAccessor(take)
    start = RPR_GetAudioAccessorStartTime(accessor)
    end = RPR_GetAudioAccessorEndTime(accessor)
    sample_length_sec = RPR_parse_timestr_len(search_area, 0, 4)
    end -= sample_length_sec

    ret = int()
    start_buf = list([0] * 2 * search_area)
    end_buf = list([0] * 2 * search_area)

    (ret, start_buf) = RPR_GetAudioAccessorSamples(
        accessor, 44100, 2, start, search_area, start_buf)
    if ret == 1:
        pr('is audio\n')

    if ret == 0:
        pr('is not audio\n')
    if ret == -1:
        pr('error\n')
    (ret, end_buf) = RPR_GetAudioAccessorSamples(
        accessor, 44100, 2, end, search_area, end_buf)

    # pr('start buffer: %s \n' % start_buf)

    points = get_loop_points(start_buf, end_buf, search_area, 5)

    start += RPR_parse_timestr_len(points[0], 0, 4)
    end += RPR_parse_timestr_len(points[1], 0, 4)
    pr('start: %s, end: %s\n' % (start, end))
    return (start, end)


def get_loop_points(start_buf, end_buf, search_area, presigion):
    starts = list()
    ends = list()
    for idx in range(search_area // 2):
        starts.append(sample_from_index(start_buf, idx, presigion))
        ends.append(sample_from_index(end_buf, idx, presigion))

    # pr('\n')
    # pr('starts: %s' % starts)
    # pr('\n')
    # pr('ends: %s' % ends)
    # pr('\n')
    for idx, val in enumerate(starts):
        if val in ends:
            pr(val)
            start = idx
            end = ends.index(val)
            pr('\n')
            return (start, end)


def sample_from_index(buf, idx, presigion):
    sample1 = buf[idx * 2]
    sample2 = buf[idx * 2 + 1]
    sample1 = int(float(sample1) * 100000) / 100000
    sample2 = int(float(sample2) * 100000) / 100000
    return (sample1, sample2)

И вывод в консоль вполне себе обнадеживающий:
Код:
is audio
(0.00414, -0.00149)
start: 0.004854166666666666, end: 1.0648958333333367
(0.004854166666666666, 1.0648958333333367)

Но вот когда я пытаюсь обрезать руками итем по полученным временным отметкам, получается, что сэмплы-то нифига не одинаковые...
2018-05-25_08-58-10.png

[DOUBLEPOST=1527213897][/DOUBLEPOST]вообще идея следющая: найти в указанном тайи-селекшн две точки, в которых сэмплы максимально близки по значению друг с другом, а потом дополнить условие окном, в котором сравниваются близлешайшие отрезки в одном направлении с меньшим разрешением (допустимой погрешностью)
 
@PianoIst, честно говоря задачу до конца так и не понял :(
Пиковые, или любые другие значения уровней, ни как не характеризуют одинаковость сэмплов. Тебе прийдется сравнивать посэмплово.
 
@Aleksandr Oleynik, задача - сделать бесшовный сустейн луп. Грубо говоря (и это самый проблемный вариант), синус режем, перемещаем как в посте выше, и получаем каку.
Сэмпл я имел ввиду именно точки уровней, которые 44100 в секунду. Вот мне и интересно, почему когда я нахожу время, на котором они одинаковые (дальше уже можно будет усложнять задачу матчинга), и я верю, что нахожу, но режу неправильно(
[DOUBLEPOST=1527228452][/DOUBLEPOST]Как вообще посэмплово по аудио-ацессору передвигаться? Может я в секунды плохо конвертирую?
 
так, судя по всему, точки я нахожу правильно, но что-то происходит при конвертации в секунды. Потому что стоит чуть-чуть подвинуть конец вперед, и все срастается
 
от, видимо, где собака порылась
https://github.com/ReaTeam/ReaScripts-Templates/blob/master/Audio/Working with audio samples.lua
Код:
-- Loop through the audio, one block at a time
    local starttime_sec = range_start
    for cur_block = 0, n_blocks do

        -- The last iteration will almost never be a full block
        if cur_block == n_blocks then block_size = extra_spls end
       
        samplebuffer.clear()   
       
        -- Loads 'samplebuffer' with the next block
GetSamples(audio, samplerate, n_channels, starttime_sec, block_size, samplebuffer)
объясните мне строчку
Код:
 -- The last iteration will almost never be a full block
        if cur_block == n_blocks then block_size = extra_spls end
что такое then?)
Получается, что "дешево" взять конкретную точку с конца нельзя, если я правильно понял. Надо, как с доступом к файлу - читать все
[DOUBLEPOST=1527241141][/DOUBLEPOST]а, не, вотоно:)
Код:
starttime_sec = starttime_sec + ((block_size * n_channels) / samplerate)
Кароч, я где-то что-то просто пропустил, ща попробуем этот способ)
 

Сейчас просматривают