Как сделать моно midi с помощью встроенных плагинов?

  • Автор темы Автор темы kovarny
  • Дата начала Дата начала

kovarny

Member
16 Май 2018
44
7
8
34
Мне нужно сделать так чтобы при игре на midi клавишах звучала и записывалась только одна нота взятая самой первой, а чтобы остальные ноты не звучали и не записывались. Цель - записывать одноголосную партию так чтобы при переходе от одной ноты к другой они не наслаивались друг на друга. В общем все как в моно синтезаторах. Как сделать? Во многих синтах есть такая встроенная опция легато, которую можно включать и выключать, а я хочу это реализовать внутри самого рипера за счет его аппаратных средств
 
@kovarny, словами задачу описали верно, а алгоритм неправильно.
Пришлю через... сегодня, короче
[DOUBLEPOST=1527710231][/DOUBLEPOST]да, сразу вдогонку вопрос:
Снимаем ноту стык-в-сытк, или с наслоением?
 
Мне нужно чтобы уже при игре записывалось стык-в-стык, например держу одну ноту - она пишется, нажимаю вторую - она не проигрывается и не пишется, отжимаю первую - первая тут же прекращается без релиза (хотя с релизом не принципиально, я могу его сам в ноль выставить в настройках синта), вторая тут же начинает проигрываться с полноценной атакой (а не переходом слайдом от первой ноты) и записываться.
 
как вариант посмотреть в видео с reaper midi step recording
Немного не так как требовалось но добиться можно
 
@Erundolog, каша в формулировках.
Сделал то, что предполагается под моно у синтов:
-первая нота играет
-вторая нота глушит первую
-если отпускаем вторую ноту и держим первую - вторая нота глушится, а первая стартует
-если отпускаем вторую ноту, а первая уже не держится - просто глушим вторую.

И так до 10 нот, зажатых одновременно. Делать небольшое наложение (тру-легато) мне было лень. Может доделаю на днях

открыть input-fx трека
в окне поиска эффектов выбрать:
2018-05-31_17-59-57.png


вставить код в открывшееся окно и сохранить
Код:
desc:MIDI legato (no notes overlaping) by Levitanus

slider1:0<0,1,{off,on}>-legato_delay

@init
    notes = 100;
    notes[0] = 0;
    notes[1] = 0;
    notes[2] = 0;
    notes[3] = 0;
    notes[4] = 0;
    notes[5] = 0;
    notes[6] = 0;
    notes[7] = 0;
    notes[8] = 0;
    notes[9] = 0;

    noteon_cnt = 0;
    last_velocity = 0;
    last_note = -1;
    #print = "start";

function add_note_to_pool(note)
local(pos)(
    noteon_cnt += 1;
    notes[noteon_cnt*2] = note;
    notes[noteon_cnt*2+1] = 2;
);
function mute_last_note(note)
local(pos, idx, flag)(
    idx = 0;
    flag = 1;
    while(idx<10 && flag == 1)(
        notes[idx*2+1] == 2?(
            notes[idx*2+1] = -1;
            flag = 0;
        );
        idx += 1;
    );
);
function delete_note_from_list(idx)
local(inc_idx)(
    noteon_cnt -= 1;
    inc_idx = idx+1;
    while(inc_idx<10)(
        notes[(inc_idx-1)*2] = notes[inc_idx*2];
        notes[(inc_idx-1)*2+1] = notes[inc_idx*2+1];
        inc_idx+=1
    );
);
function kill_overlaps(offset)
local (idx, flag)(
    idx = 0;
    flag = 1;
    while(idx < 10)(
        notes[idx * 2 + 1] == -1?(
            midisend(offset, $x80, notes[idx * 2], 0);
            notes[idx * 2 + 1] = 1;
        );
        notes[idx * 2 + 1] == -2?(
            notes[idx * 2+1] = 0;
            midisend(offset, $x80, notes[idx * 2], 0);
            // delete_idx = idx+1;
            delete_note_from_list(idx);
            // flag = 0;
            // idx+=1
        );
        idx+=1
    );
);

function delete_note(note)
local(idx, flag)(
    idx = 0;
    flag = 1;
    while(idx<10 && flag == 1)(
        notes[idx*2] == note?(
            notes[idx*2+1] == 1?(
                delete_note_from_list(idx);
            ):(
                notes[idx * 2+1] = -2;
            );
            flag = 0;
        );
        idx+=1
    );
);

function on_note(note, velocity, offset)
local (ignore, idx, flag)(
    ignore = 0;
    last_velocity = velocity;
    last_note = note;
  

    noteon_cnt>0?(
        mute_last_note()
    );
    add_note_to_pool(note);
    slider1 == 0?(
        kill_overlaps(offset);
    );
    ignore;
);

function play_last_note()
local(idx, flag)(
    noteon_cnt>0?(
        notes[noteon_cnt * 2+1] = 2;
        new_note = notes[noteon_cnt * 2];
        midisend(offset, $x90, new_note, last_velocity);
        last_note = new_note;
    );
);

function on_release(note, offset)
local (ignore, islastnote, new_note)(
    ignore = 1;
    islastnote = 0;
    note == last_note?(
        islastnote = 1;
    );
    // delete current note
    delete_note(note);
    slider1 == 0?( // delete it completely if no overlapping
        kill_overlaps(offset);
    );
    //
    islastnote == 1?(
        play_last_note();
    );
    ignore;
);


@block
    kill_overlaps(0);
    while (midirecv(offset,msg1,msg2,msg3)) ( // REAPER 4.59+ syntax while()
        msg1==$x90? (
            msg3!=0?( // on note
                ignore = on_note(msg2, msg3, offset);
                ignore==0?(
                    midisend(offset,msg1,msg2,msg3);
                );
            ) : ( // on release
                ignore = on_release(msg2, offset);
                ignore==0?(
                    midisend(offset,msg1,msg2,msg3);
                );
            );
        ) : ( msg1==$x80?( // on release
                ignore = on_release(msg2, offset);
                ignore==0?(
                    midisend(offset,msg1,msg2,msg3);
                );
            ) : (
                midisend(offset,msg1,msg2,msg3); // passthrough other events
            );
        );
    );
[DOUBLEPOST=1527764579][/DOUBLEPOST]
первая тут же прекращается без релиза
это не от миди зависит.

вторая тут же начинает проигрываться с полноценной атакой
а зачем так коряво-то? хз как это играть) Есть нормальный, как у всех синтов моно)
[DOUBLEPOST=1527764778][/DOUBLEPOST]видяха
 
  • Like
Реакции: kovarny
Спасибо, вроде то что надо, правда я хотел немного по другому переключение с первой на вторую ноту, но вроде и так с поставленной задачей справляется. Только вот если байпасить плагин с звучащей нотой то рипер зависает и вылетает
 

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