Syncing piano rolls
-
Clearscreen
- Member
- Posts: 482
- Location: Australia
- Contact:
i'm using a few different piano rolls in different tracks and using the track enable/disable to drop them in and out. problem is, unless i use quantise on the triggering the syncing is easy to lose. i want to use 'loop' as my sync option in the piano roll as i'm using different length loops in each piano roll but ideally i'd like to have 'cycle' or 'bar' style syncing in that the loop syncs to bar start.
it'd be nice to have a sync option in the piano roll that was synced to bar position if you know what i mean? so that when i reactivate the track it jumps to the correct position in the bar without being limited by the cycle loop length or the bar length. i've played around with a mix of master and local sync modules and creating midi clock etc but i can't get anything to work quite right - anyone have any suggestions?
it'd be nice to have a sync option in the piano roll that was synced to bar position if you know what i mean? so that when i reactivate the track it jumps to the correct position in the bar without being limited by the cycle loop length or the bar length. i've played around with a mix of master and local sync modules and creating midi clock etc but i can't get anything to work quite right - anyone have any suggestions?
not a expert about bar ,maybe a math conversion linked to the start pos of your piano roll...?
+1 for this issue
i've tried to do a midi looper with dynamic bar lengths and never could achieve good timing.
havent retried for a while thu. havent got a solution.. just some loud thinking here
what u could do of course, clearscreen is to keep all tracks active and use a midi bypass (flow control works also for midi streams).
thorny it gets if i change the loop ranges while playing, apply reverse or whatever (further, even worse when i wanted to realtime record).
maybe the easiest and most common way (as in many hardware seqs) could be to force every piano roll to wait until the longest piano roll (like a master track) has reached its first bar. then again u could use quantized triggers too..
however there should be a more dynamic way (= when rolls are turned off, or loop range is changed) to ensure the constraint all rolls should meet at the first bar as fast as possible?
for inspiration u coould check (sadly discontinued) Phrazor vst which does midi clip muting/unmuting very nicely.
i've tried to do a midi looper with dynamic bar lengths and never could achieve good timing.
havent retried for a while thu. havent got a solution.. just some loud thinking here
what u could do of course, clearscreen is to keep all tracks active and use a midi bypass (flow control works also for midi streams).
thorny it gets if i change the loop ranges while playing, apply reverse or whatever (further, even worse when i wanted to realtime record).
maybe the easiest and most common way (as in many hardware seqs) could be to force every piano roll to wait until the longest piano roll (like a master track) has reached its first bar. then again u could use quantized triggers too..
however there should be a more dynamic way (= when rolls are turned off, or loop range is changed) to ensure the constraint all rolls should meet at the first bar as fast as possible?
for inspiration u coould check (sadly discontinued) Phrazor vst which does midi clip muting/unmuting very nicely.
Perhaps you could try to search in this way, if you don't use any odd signature:

The get bus module gets the ppq position from a master piano roll.
In the A<B and A>B modules, B is set to same as your piano roll inlet "end position".
In this example, the master piano roll have got a lenght of 64. In the mapper module, i remap values from 32 to 64, to 0 to 32...

The get bus module gets the ppq position from a master piano roll.
In the A<B and A>B modules, B is set to same as your piano roll inlet "end position".
In this example, the master piano roll have got a lenght of 64. In the mapper module, i remap values from 32 to 64, to 0 to 32...
Seb.Dub
-
Clearscreen
- Member
- Posts: 482
- Location: Australia
- Contact:
In all seriousness - you guys are great!
some excellent suggestions there!!
a late response to this issue...
@ethnix: not totally sure but i believe ur solution changes the play speed of the slaved (means: synced) roll?
i've been messing around with a script solution. my goal was to achieve the same behavior as in phrazor. didnt quite get there

it works ok under some circumstances. to do's:
- proper sync if slave roll's start bar is not 0 and slave bar length is different than master bar length.
- meaningful sync with non-integer bar lengths ratios
- also sync on reverse mode
- many things more!
however, i've quit working on it cause things might change with usine v5. also i am not sure if manipulating ppq streams with a midi script is a goof idea (tests did not show sync or cpu issues thu)?
if any1 interested, here the code.
@ethnix: not totally sure but i believe ur solution changes the play speed of the slaved (means: synced) roll?
i've been messing around with a script solution. my goal was to achieve the same behavior as in phrazor. didnt quite get there

it works ok under some circumstances. to do's:
- proper sync if slave roll's start bar is not 0 and slave bar length is different than master bar length.
- meaningful sync with non-integer bar lengths ratios
- also sync on reverse mode
- many things more!
however, i've quit working on it cause things might change with usine v5. also i am not sure if manipulating ppq streams with a midi script is a goof idea (tests did not show sync or cpu issues thu)?
if any1 interested, here the code.
Code: Select all
(*/////////////////////////////////////////////////////
// MEP_rollSync - midi script for sensomusic usine
// version: 2009-10-03 0.1; author: amiga909
<<<WHAT>>>
syncs 2 piano rolls with different lengths
<<<HOW>>>
- both rolls in [loop mode]
- master bar length may not be shorter than slave
- master must start at the first bar (start pos = 0)
<<INPUT>>
*bypass if ON: output PPQ is not adjusted
end pos.master connect to 1st piano roll module outlet
ppQpos.master connect to 1st piano roll module outlet
start pos.slave1 connect to 2nd piano roll module outlet
end pos.slave1 connect to 2nd piano roll module outlet
<<OUTPUT>>
ppQpos.slave1 connect to 2nd piano roll module inlet
end pos.slave1 connect to 2nd piano roll module inlet
//////////////////////////////////////////////////////
*)
//////////////////////////
// roll sync
// what: resets and/or freezes a slaved piano roll
// master + slave concurrently play their first bar as soon as possible
/////////////////////////
// parameters declaration
VAR pIn, pOut, pBypass, //pOutStop,
pMasterBarLength, pSlave1BarStart, pSlave1BarLength : tParameter;
VAR masterBar, slave1Bar, slave1Offset, intervalSlave1: INTEGER;
VAR ppqIn: DOUBLE;
// init
PROCEDURE init;
BEGIN
pBypass := createParam('*bypass', ptButton);
pMasterBarLength := createParam('end pos.master', ptDataFader);
pIn := createParam('ppQpos.master', ptDataField);
pSlave1BarStart := createParam('start pos.slave1', ptDataFader);
pSlave1BarLength := createParam('end pos.slave1', ptDataFader);
pOut := createParam('ppQpos.slave1', ptDataField);
setValue(pMasterBarLength, 4);
setValue(pBypass, 0);
setValue(pSlave1BarStart,0);
setValue(pMasterBarLength,2);
setIsInput(pOut,FALSE);
setIsOutput(pIn,FALSE);
setIsOutput(pBypass,FALSE);
setIsOutput(pSlave1BarLength ,FALSE);
setIsOutput(pSlave1BarStart ,FALSE);
setIsOutput(pMasterBarLength ,FALSE);
END;
//////////////////////////////
// main
//////////////////////////////
begin
IF ((getValue(pBypass) = 0)) THEN BEGIN
masterBar := TRUNC(getValue(pMasterBarLength));
slave1Offset := TRUNC(getValue(pSlave1BarStart));
slave1Bar := TRUNC(getValue(pSlave1BarLength));
// interval: 0: slave same length; -: slave is longer; +: slave is shorter
intervalSlave1 := masterBar - (slave1Bar - slave1Offset);
IF (slave1Offset = 0) THEN BEGIN
// CASE 1: DONE
IF (intervalSlave1 > 0) THEN BEGIN
// init PPQ var
ppqIn := getValue(pIn);
IF (ppqIn > slave1Bar) THEN BEGIN
ppqIn := ppqIn - (TRUNC(ppqIn / slave1Bar) * slave1Bar);
setValue(pOut, ppqIn);
END
ELSE BEGIN
setValue(pOut, ppqIn);
END;
END
ELSE IF (intervalSlave1 = 0) THEN BEGIN
// CASE 2: DONE
setValue(pOut, getValue(pIn));
END
ELSE BEGIN // (intervalSlave1 < 0)
// CASE 3: DONE // master is never shorter than slave!
//setValue(pSlave1BarLengthOut, masterBar);
END;
END
ELSE BEGIN //(slave1Offset > 0)
IF (intervalSlave1 > 0) THEN BEGIN
// CASE 4:
ppqIn := getValue(pIn);
IF (ppqIn < slave1Offset) THEN BEGIN
ppqIn := ppqIn + (TRUNC(ppqIn / slave1Bar) * slave1Bar);
setValue(pOut, ppqIn);
END
ELSE BEGIN
setValue(pOut, ppqIn);
END;
END
ELSE IF (intervalSlave1 = 0) THEN BEGIN
// CASE 5: DONE
setValue(pOut, (getValue(pIn) + slave1Offset));
END
ELSE BEGIN // (intervalSlave1 < 0)
// CASE 6: DONE
//setValue(pSlave1BarLengthOut, (masterBar + slave1Offset));
END;
END;
END
ELSE BEGIN
setValue(pOut, getValue(pIn));
END;
end.@amiga909: I would need to test another time, but if i'm not mistaken, my last test didn't change play speed of the slaved piano roll...
Il will test your script , as it might be really usefull
Il will test your script , as it might be really usefull
Seb.Dub
Setup your tracks under the sequencer.
Export your piano rolls to a MIDI file, then drag and drop them into the sequencer under the same number tracks you already have. Set up a loop under the sequencer's ruler. Then play and then drop them in and out the way you used to.
It is important that you drag and drop your MIDI file so you get the right module and things will stay in sync.
Export your piano rolls to a MIDI file, then drag and drop them into the sequencer under the same number tracks you already have. Set up a loop under the sequencer's ruler. Then play and then drop them in and out the way you used to.
It is important that you drag and drop your MIDI file so you get the right module and things will stay in sync.
Who is online
Users browsing this forum: Google [Bot] and 27 guests
