RNBO Link to MIDI Clock Patch Jitter-Help?
Hi all,
So, this has been driving me a bit nuts, and I'm going to go out on a limb and hope that it is pilot error. I started out with Max mainly with RNBO, and so most of what I've been able to figure out is trying to adapt Max knowledge into RNBO.
So, most of my patches have been using Ableton Link for Tempo Sync and it is solid, but I've been trying to add a MIDI clock out to my FX patches as well from the Ableton Link transport clock. It works, but wowzers, the jitter is crazy. It isn't minor either, I'm getting massive jumps of 3-5bpm at times within a second or two. I've seen all sorts of references to using phasor, doing rounding, etc, but there have not been any example patches to learn from.
The clock is made to always be sending, and have no notion of start/stop. This is intentional, as a lot of drum machines/synths take a few extra MS to catch the BPM before start, so by always sending I can prep the machines in advance.
If someone could tell me what I am doing wrong I would be eternally grateful.
(Note, if dropping into Max, remember that this is RNBO. So the Param object should be replaced.
{
"boxes" : [ {
"box" : {
"maxclass" : "newobj",
"text" : "t 248",
"outlettype" : [ "" ],
"patching_rect" : [ 254.0, 360.0, 37.0, 23.0 ],
"numinlets" : 1,
"id" : "obj-2",
"numoutlets" : 1,
"rnboinfo" : {
"needsInstanceInfo" : 1,
"argnames" : {
"out1" : {
"attrOrProp" : 1,
"digest" : "Output order 1 (number).",
"defaultarg" : 1,
"isalias" : 0,
"aliases" : [ ],
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"outlet" : 1,
"type" : "number"
}
,
"triggers" : {
"attrOrProp" : 2,
"digest" : "The number of arguments determines the number of outlets. \t\t\t\t\t\tEach outlet sends out either a whole number, float, bang or list, \t\t\t\t\t\tas identified by symbol arguments (i, f, b, l). \t\t\t\t\t\tIf there are no arguments, there are two outlets, both of which send a float.",
"defaultarg" : 1,
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "list"
}
}
,
"inputs" : [ {
"name" : "input",
"type" : [ "bang", "number", "list" ],
"digest" : "input to distribute",
"hot" : 1,
"docked" : 0
}
],
"outputs" : [ {
"name" : "out1",
"type" : "number",
"digest" : "Output order 1 (number).",
"defaultarg" : 1,
"docked" : 0
}
],
"helpname" : "trigger",
"aliasOf" : "trigger",
"classname" : "t",
"operator" : 0,
"versionId" : -1133428571,
"changesPatcherIO" : 0
}
,
"rnbo_extra_attributes" : {
"triggers" : ""
}
,
"rnbo_uniqueid" : "t_obj-2",
"rnbo_serial" : 3,
"rnbo_classname" : "t"
}
}
, {
"box" : {
"maxclass" : "comment",
"text" : "MIDI Clock out",
"patching_rect" : [ 242.5, 396.0, 102.5, 21.0 ],
"numinlets" : 1,
"id" : "obj-23",
"numoutlets" : 0
}
}
, {
"box" : {
"maxclass" : "comment",
"text" : "Start/Stop clock",
"patching_rect" : [ 155.0, 138.0, 128.0, 21.0 ],
"numinlets" : 1,
"id" : "obj-20",
"numoutlets" : 0
}
}
, {
"box" : {
"maxclass" : "newobj",
"text" : "/ 20",
"outlettype" : [ "" ],
"patching_rect" : [ 246.0, 283.0, 31.0, 23.0 ],
"numinlets" : 2,
"id" : "obj-8",
"numoutlets" : 1,
"rnbo_extra_attributes" : {
"hot" : 0
}
,
"rnbo_uniqueid" : "/_obj-8",
"rnbo_serial" : 2,
"rnbo_classname" : "/"
}
}
, {
"box" : {
"maxclass" : "newobj",
"text" : "metro @interval 1 ticks @active 1",
"outlettype" : [ "" ],
"patching_rect" : [ 172.5, 174.0, 190.0, 23.0 ],
"numinlets" : 2,
"id" : "obj-4",
"numoutlets" : 1,
"rnbo_extra_attributes" : {
"lock" : 0.0
}
,
"rnbo_uniqueid" : "metro_obj-4",
"rnbo_serial" : 2,
"rnbo_classname" : "metro"
}
}
, {
"box" : {
"maxclass" : "newobj",
"text" : "transport",
"outlettype" : [ "", "", "", "", "", "", "", "" ],
"patching_rect" : [ 172.5, 237.0, 103.0, 23.0 ],
"numinlets" : 2,
"id" : "obj-1",
"numoutlets" : 8,
"rnbo_uniqueid" : "transport_obj-1",
"rnbo_serial" : 1,
"rnbo_classname" : "transport"
}
}
, {
"box" : {
"maxclass" : "newobj",
"varname" : "clockstart",
"text" : "param clockstart @value 20 @enum stop start",
"outlettype" : [ "", "" ],
"patching_rect" : [ 45.0, 48.5, 250.0, 23.0 ],
"numinlets" : 2,
"id" : "obj-28",
"numoutlets" : 2,
"rnboinfo" : {
"needsInstanceInfo" : 1,
"argnames" : {
"value" : {
"attrOrProp" : 2,
"digest" : "Set initial value",
"defaultarg" : 2,
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "number",
"defaultValue" : "0",
"label" : "Initial Value",
"displayorder" : 3
}
,
"normalizedvalue" : {
"attrOrProp" : 1,
"digest" : "Set value normalized. ",
"isalias" : 0,
"aliases" : [ ],
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"inlet" : 1,
"type" : "number"
}
,
"reset" : {
"attrOrProp" : 1,
"digest" : "Reset param to initial value",
"isalias" : 0,
"aliases" : [ ],
"attachable" : 1,
"isparam" : 0,
"deprecated" : 0,
"type" : "bang"
}
,
"normalized" : {
"attrOrProp" : 1,
"digest" : "Normalized parameter value.",
"isalias" : 0,
"aliases" : [ ],
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"outlet" : 1,
"type" : "number"
}
,
"name" : {
"attrOrProp" : 2,
"digest" : "Name of the parameter",
"defaultarg" : 1,
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "symbol",
"label" : "Parameter Name",
"mandatory" : 1
}
,
"enum" : {
"attrOrProp" : 2,
"digest" : "Use an enumerated output",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "list",
"label" : "Enum Values",
"displayorder" : 6
}
,
"minimum" : {
"attrOrProp" : 2,
"digest" : "Minimum value",
"isalias" : 0,
"aliases" : [ "min" ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "number",
"defaultValue" : "0",
"label" : "Minimum",
"displayorder" : 1
}
,
"min" : {
"attrOrProp" : 2,
"digest" : "Minimum value",
"isalias" : 1,
"aliasOf" : "minimum",
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "number",
"defaultValue" : "0",
"label" : "Minimum",
"displayorder" : 1
}
,
"maximum" : {
"attrOrProp" : 2,
"digest" : "Maximum value",
"isalias" : 0,
"aliases" : [ "max" ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "number",
"defaultValue" : "1",
"label" : "Maximum",
"displayorder" : 2
}
,
"max" : {
"attrOrProp" : 2,
"digest" : "Maximum value",
"isalias" : 1,
"aliasOf" : "maximum",
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "number",
"defaultValue" : "1",
"label" : "Maximum",
"displayorder" : 2
}
,
"exponent" : {
"attrOrProp" : 2,
"digest" : "Scale values exponentially",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "number",
"defaultValue" : "1",
"label" : "Exponent",
"displayorder" : 7
}
,
"steps" : {
"attrOrProp" : 2,
"digest" : "Divide the output into a number of discrete steps",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "number",
"defaultValue" : "0",
"label" : "Steps",
"displayorder" : 8
}
,
"displayName" : {
"attrOrProp" : 2,
"digest" : "DEPRECATED: Use the lower case 'displayname' instead",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 1,
"type" : "symbol",
"label" : "Display Name"
}
,
"displayname" : {
"attrOrProp" : 2,
"digest" : "A more readable name for the parameter in an external RNBO target",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "symbol",
"defaultValue" : "",
"label" : "Display Name",
"displayorder" : 14
}
,
"unit" : {
"attrOrProp" : 2,
"digest" : "A symbol to describe the unit of the parameter in an external RNBO target",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "symbol",
"defaultValue" : "",
"label" : "Unit",
"displayorder" : 15
}
,
"tonormalized" : {
"attrOrProp" : 2,
"digest" : "Converts a real parameter value to its normalized form.",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "symbol",
"label" : "To Normalized Expression",
"displayorder" : 10
}
,
"fromnormalized" : {
"attrOrProp" : 2,
"digest" : "Converts a normalized parameter into its actual parameter value.",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "symbol",
"label" : "From Normalized Expression",
"displayorder" : 9
}
,
"order" : {
"attrOrProp" : 2,
"digest" : "Order in which initial parameter values will be sent out on patcher load. The order can be numeric or symbolic ('first' and 'last')",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "symbol",
"defaultValue" : "0",
"label" : "Restore Order",
"displayorder" : 12
}
,
"displayorder" : {
"attrOrProp" : 2,
"digest" : "Order in which parameters will show up in a list of all parameters. The order can be numeric or symbolic ('first' and 'last')",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "symbol",
"defaultValue" : "-",
"label" : "Display Order",
"displayorder" : 13
}
,
"sendinit" : {
"attrOrProp" : 2,
"digest" : "Send initial value",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "bool",
"defaultValue" : "true",
"label" : "Send Init",
"displayorder" : 4
}
,
"ctlin" : {
"attrOrProp" : 2,
"digest" : "MIDI controller number to control this parameter.",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "number",
"label" : "MIDI Controller Number.",
"displayorder" : 16
}
,
"meta" : {
"attrOrProp" : 2,
"digest" : "A JSON formatted string containing metadata for use by the exported code",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "symbol",
"defaultValue" : "",
"label" : "Metadata",
"displayorder" : 17
}
,
"nopreset" : {
"attrOrProp" : 2,
"digest" : "Do not add this value to the preset [DEPRECATED - USE @preset 0 instead].",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 1,
"type" : "bool",
"defaultValue" : "false"
}
,
"preset" : {
"attrOrProp" : 2,
"digest" : "Add this value to the preset.",
"isalias" : 0,
"aliases" : [ ],
"settable" : 1,
"attachable" : 0,
"isparam" : 0,
"deprecated" : 0,
"type" : "bool",
"defaultValue" : "true",
"label" : "Include In Preset",
"displayorder" : 11
}
}
,
"inputs" : [ {
"name" : "value",
"type" : "number",
"digest" : "Parameter value",
"hot" : 1,
"docked" : 0
}
, {
"name" : "normalizedvalue",
"type" : "number",
"digest" : "Set value normalized. ",
"docked" : 0
}
],
"outputs" : [ {
"name" : "value",
"type" : "number",
"digest" : "Parameter value",
"hot" : 1,
"docked" : 0
}
, {
"name" : "normalized",
"type" : "number",
"digest" : "Normalized parameter value.",
"docked" : 0
}
],
"helpname" : "param",
"aliasOf" : "param",
"classname" : "param",
"operator" : 0,
"versionId" : -1696900560,
"changesPatcherIO" : 0
}
,
"rnbo_extra_attributes" : {
"exponent" : 1.0,
"ctlin" : 0.0,
"tonormalized" : "",
"displayname" : "",
"minimum" : 0.0,
"maximum" : 1.0,
"sendinit" : 1,
"fromnormalized" : "",
"steps" : 0.0,
"preset" : 1,
"unit" : "",
"meta" : "",
"displayorder" : "-",
"order" : "0"
}
,
"rnbo_uniqueid" : "clockstart",
"rnbo_serial" : 2,
"rnbo_classname" : "param"
}
}
, {
"box" : {
"maxclass" : "toggle",
"outlettype" : [ "int" ],
"patching_rect" : [ 45.0, 95.5, 46.0, 46.0 ],
"numinlets" : 1,
"id" : "obj-85",
"parameter_enable" : 0,
"numoutlets" : 1,
"rnbo_extra_attributes" : {
"preset" : 0,
"order" : ""
}
,
"rnbo_uniqueid" : "toggle_obj-85",
"rnbo_serial" : 1,
"rnbo_classname" : "toggle"
}
}
],
"lines" : [ {
"patchline" : {
"source" : [ "obj-28", 0 ],
"destination" : [ "obj-85", 0 ]
}
}
, {
"patchline" : {
"source" : [ "obj-85", 0 ],
"destination" : [ "obj-1", 0 ]
}
}
, {
"patchline" : {
"source" : [ "obj-8", 0 ],
"destination" : [ "obj-2", 0 ]
}
}
, {
"patchline" : {
"source" : [ "obj-4", 0 ],
"destination" : [ "obj-1", 0 ]
}
}
, {
"patchline" : {
"source" : [ "obj-1", 7 ],
"destination" : [ "obj-8", 0 ]
}
}
],
"appversion" : {
"major" : 8,
"minor" : 5,
"revision" : 6,
"architecture" : "x64",
"modernui" : 1
}
,
"classnamespace" : "rnbo"
}
Sorry about the paste above. It isn't actually a working one anyway, it works in max but not in RNBO. Here is the simplest clock patch. The results are identical using transport or a raw Metro feed, but ideally I would like to go this route as I am not using the transport in any of the patch.

why do you need transport at all ?
is metro set to beatclock ticks interval and lock 1
not supposed to follow host sync ?
I don't know if rnbo can sync well that way, but using only needed objects
helps sometimes in max.
I don't use ableton and can't say if it makes sense to sync to live link and
generate another clock out of synced plugins.
I don't need transport, that is where I started at. The picture is where I'm at now. The clock in the pic is set to 20 ticks as the issue that I've found is that the / function works when using Max, but doesn't work when using RNBO.
The idea is to be able to have the Pi send MIDI clock to hardware that is connected. Ableton Link is only for sending tempo to the Pi when using an application that sends Link but not MIDI clock.....which there are too many of. The clock works well when sending to RNBO, it is only when trying to send MIDI clock that things fall apart a bit due to jitter.
Hey Drew,
"most of my patches have been using Ableton Link for Tempo Sync and it is solid, but I've been trying to add a MIDI clock out to my FX patches as well from the Ableton Link transport clock."
So, do you mean that your patches running on the PI work fine with Link tempo sync, like generating audio etc there, but the MIDI clock out is jittery?
Are you using metro in your FX patches as well? Or.. what are you using there that does sync? phasor~?
Okay, I'm seeing an issue with midi event timestamps in the RNBO code.. I'll be looking into this
Hi Alex,
I'm using Metro in the FX patches, yes. Thank you so much for looking into it! I appreciate it very much.
I just merged a fix for the MIDI timing issue but it won't be available until we do another RNBO release, I'm not sure when that will be.
I got this update into the latest release
https://cycling74.com/forums/rnbo-122-released