Welcome to %s forums

BrainModular Users Forum

Login Register

Syncing piano rolls

General Discussion about whatever fits..
Post Reply
Clearscreen
Member
Posts: 482
Location: Australia
Contact:

Unread post by Clearscreen » 19 Aug 2009, 03:23

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?

User avatar
nay-seven
Site Admin
Posts: 5684
Location: rennes France
Contact:

Unread post by nay-seven » 19 Aug 2009, 09:45

not a expert about bar ,maybe a math conversion linked to the start pos of your piano roll...?

amiga909
Member
Posts: 324
Contact:

Unread post by amiga909 » 19 Aug 2009, 09:48

+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.

ethnix73
Member
Posts: 604
Location: France, Caen
Contact:

Unread post by ethnix73 » 19 Aug 2009, 17:49

Perhaps you could try to search in this way, if you don't use any odd signature:

Image

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:

Unread post by Clearscreen » 20 Aug 2009, 00:11

In all seriousness - you guys are great! :) some excellent suggestions there!!

amiga909
Member
Posts: 324
Contact:

Unread post by amiga909 » 18 Oct 2009, 11:02

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 :(
Image
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

&#40;*/////////////////////////////////////////////////////
// MEP_rollSync -  midi script for sensomusic usine 
// version&#58; 2009-10-03 0.1; author&#58; amiga909

<<<WHAT>>>
syncs 2 piano rolls with different lengths 

<<<HOW>>>
- both rolls in &#91;loop mode&#93;
- master bar length may not be shorter than slave
- master must start at the first bar &#40;start pos = 0&#41;

<<INPUT>> 
*bypass 				if ON&#58; 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

	
//////////////////////////////////////////////////////
*&#41;

//////////////////////////
// roll sync
// what&#58; 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 &#58; tParameter;
  
VAR masterBar, slave1Bar, slave1Offset, intervalSlave1&#58; INTEGER;
VAR ppqIn&#58; DOUBLE;

// init 
PROCEDURE init;
BEGIN
	pBypass &#58;= createParam&#40;'*bypass', ptButton&#41;; 
	pMasterBarLength &#58;= createParam&#40;'end pos.master', ptDataFader&#41;;
	pIn &#58;= createParam&#40;'ppQpos.master', ptDataField&#41;;   
	pSlave1BarStart &#58;= createParam&#40;'start pos.slave1', ptDataFader&#41;; 
	pSlave1BarLength &#58;= createParam&#40;'end pos.slave1', ptDataFader&#41;;  
	
	pOut &#58;= createParam&#40;'ppQpos.slave1', ptDataField&#41;; 

	setValue&#40;pMasterBarLength, 4&#41;;
	setValue&#40;pBypass, 0&#41;;
	setValue&#40;pSlave1BarStart,0&#41;;
	setValue&#40;pMasterBarLength,2&#41;;
	 
	setIsInput&#40;pOut,FALSE&#41;;
	setIsOutput&#40;pIn,FALSE&#41;;
	setIsOutput&#40;pBypass,FALSE&#41;;
	setIsOutput&#40;pSlave1BarLength ,FALSE&#41;;
	setIsOutput&#40;pSlave1BarStart ,FALSE&#41;;
	setIsOutput&#40;pMasterBarLength  ,FALSE&#41;;
END;


//////////////////////////////
// main
//////////////////////////////
begin

IF &#40;&#40;getValue&#40;pBypass&#41; = 0&#41;&#41; THEN BEGIN
	masterBar &#58;= TRUNC&#40;getValue&#40;pMasterBarLength&#41;&#41;;
	slave1Offset &#58;= TRUNC&#40;getValue&#40;pSlave1BarStart&#41;&#41;;
	slave1Bar &#58;= TRUNC&#40;getValue&#40;pSlave1BarLength&#41;&#41;;
	// interval&#58; 0&#58; slave same length; -&#58; slave is longer; +&#58; slave is shorter
	intervalSlave1 &#58;= masterBar - &#40;slave1Bar - slave1Offset&#41;;
	
	IF &#40;slave1Offset = 0&#41; THEN BEGIN 
	// CASE 1&#58; DONE
		IF &#40;intervalSlave1 > 0&#41; THEN BEGIN
			// init PPQ var
			ppqIn &#58;= getValue&#40;pIn&#41;;
			IF &#40;ppqIn > slave1Bar&#41; THEN BEGIN
				ppqIn &#58;= ppqIn - &#40;TRUNC&#40;ppqIn / slave1Bar&#41; * slave1Bar&#41;;
				setValue&#40;pOut, ppqIn&#41;;
			END
			ELSE BEGIN
				setValue&#40;pOut, ppqIn&#41;;		
			END;	 
		END
		ELSE IF &#40;intervalSlave1 = 0&#41; THEN BEGIN 
	// CASE 2&#58; DONE  
			setValue&#40;pOut, getValue&#40;pIn&#41;&#41;;	
		END
		ELSE BEGIN // &#40;intervalSlave1 < 0&#41;
	// CASE 3&#58; DONE    // master is never shorter than slave!
		//setValue&#40;pSlave1BarLengthOut, masterBar&#41;; 
		END;
	
	END
	
	ELSE BEGIN //&#40;slave1Offset > 0&#41;	
		IF &#40;intervalSlave1 > 0&#41; THEN BEGIN
	// CASE 4&#58; 
		ppqIn &#58;= getValue&#40;pIn&#41;;
			IF &#40;ppqIn < slave1Offset&#41; THEN BEGIN
				ppqIn &#58;= ppqIn + &#40;TRUNC&#40;ppqIn / slave1Bar&#41; * slave1Bar&#41;;
				setValue&#40;pOut, ppqIn&#41;;
			END
			ELSE BEGIN
				setValue&#40;pOut, ppqIn&#41;;		
			END;
		END
		ELSE IF &#40;intervalSlave1 = 0&#41; THEN BEGIN 
	// CASE 5&#58; DONE
			setValue&#40;pOut, &#40;getValue&#40;pIn&#41; + slave1Offset&#41;&#41;;	
		END
		ELSE BEGIN // &#40;intervalSlave1 < 0&#41;
	// CASE 6&#58; DONE   
			//setValue&#40;pSlave1BarLengthOut, &#40;masterBar + slave1Offset&#41;&#41;; 	
		END;	
	END;
	

END
ELSE BEGIN 
setValue&#40;pOut, getValue&#40;pIn&#41;&#41;;	
END;
 

end.

ethnix73
Member
Posts: 604
Location: France, Caen
Contact:

Unread post by ethnix73 » 18 Oct 2009, 12:13

@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
Seb.Dub

Wiskow
New member
Posts: 9
Contact:

Unread post by Wiskow » 01 Jan 2010, 06:49

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.

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 27 guests