{
   "abletonlink" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "offset ms" : "offset in milliseconds to tweak synchronization",
         "reset next downbeat" : "resets measure count on the next downbeat, to help synchronize to desired phase in session"
      },
      "description" : "synchronizes transport with software and devices that support ableton link",
      "type" : "other"
   },
   "accum" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "value" : "output value",
         "velocity" : "amount to accumulate"
      },
      "description" : "accumulate a value over time",
      "type" : "modulators"
   },
   "add" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "value 1" : "value to sum",
         "value 2" : "value to sum"
      },
      "description" : "outputs the result of value 1 plus value 2. value 1 and value 2 are intended to be patch targets for modulators.",
      "type" : "modulators"
   },
   "addcentered" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "range 2" : "modulation amount",
         "value 1" : "center value",
         "value 2" : "modulation value"
      },
      "description" : "outputs the result of value 1 plus value 2, multiplied by range 2. optimized for using to modulation value 1 by range 2 at a frequency. value 1 or value 2 are intended to be patch targets for modulators.",
      "type" : "modulators"
   },
   "arpeggiator" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "interval" : "arpeggiation rate",
         "octaves" : "how many octaves to step through",
         "step" : "direction and distance to step through arpeggiation. a value of zero is \"pingpong\"."
      },
      "description" : "arpeggiates held notes. there are several vestigial features in this module that should be cleaned up.",
      "type" : "note effects"
   },
   "audiometer" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "level" : "the input audio level. hook this up to an LED-display midi control to see the value displayed on your controller."
      },
      "description" : "sets a slider to an audio level's volume. useful to map a midi display value to.",
      "type" : "audio effects"
   },
   "audiorouter" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "route" : "audio destination"
      },
      "description" : "selector for switching where audio is routed to. connect to targets to add them to the list.",
      "type" : "audio effects"
   },
   "audiosplitter" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "description" : "send an audio signal to multiple destinations",
      "type" : "audio effects"
   },
   "audiotocv" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "gain" : "multiply incoming audio",
         "max" : "maximum output value",
         "min" : "minimum output value"
      },
      "description" : "use an audio signal to modulate a control. allow for audio-rate modulation, to achieve effects such as FM.",
      "type" : "modulators"
   },
   "audiotopulse" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "release" : "the cooldown time for the audio signal before a pulse can be triggered again",
         "threshold" : "send a pulse when the signal hits this threshold"
      },
      "description" : "sends a pulse when the audio level surpasses a specified threshold",
      "type" : "pulse"
   },
   "autotalent" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "A" : "[todo]",
         "Ab" : "[todo]",
         "B" : "[todo]",
         "Bb" : "[todo]",
         "C" : "[todo]",
         "D" : "[todo]",
         "Db" : "[todo]",
         "E" : "[todo]",
         "Eb" : "[todo]",
         "F" : "[todo]",
         "G" : "[todo]",
         "Gb" : "[todo]",
         "amount" : "[todo]",
         "formant correct" : "[todo]",
         "fwarp" : "[todo]",
         "lfoamp" : "[todo]",
         "lfoquant" : "[todo]",
         "lforate" : "[todo]",
         "lfoshape" : "[todo]",
         "lfosymm" : "[todo]",
         "mix" : "[todo]",
         "scwarp" : "[todo]",
         "set from scale" : "[todo]",
         "shift" : "[todo]",
         "smooth" : "[todo]"
      },
      "description" : "[abandoned module, possibly broken]autotune using the \"autotalent\" code",
      "type" : "unknown"
   },
   "basiceq" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "even" : "reset EQ"
      },
      "description" : "simple multiband EQ",
      "type" : "effect chain"
   },
   "beats" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "bars*" : "how many measures long are the samples in this slot?",
         "delete *" : "remove the current sample from the list",
         "double*" : "enable this to play at double speed",
         "filter*" : "layer filter. negative values bring in a low pass, positive values bring in a high pass.",
         "pan*" : "layer panorama",
         "selector*" : "which sample should we play in this slot? drag samples onto here to add them to this slot.",
         "volume*" : "layer volume"
      },
      "description" : "multi-loop player, for mixing sample layers together",
      "type" : "synths"
   },
   "biquad" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "F" : "frequency cutoff",
         "G" : "gain",
         "Q" : "resonance",
         "type" : "filter type"
      },
      "description" : "filter using biquad formula",
      "type" : "effect chain"
   },
   "bitcrush" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "crush" : "sample resolution reduction",
         "downsamp" : "sample rate reduction"
      },
      "description" : "reduce sample resolution and sample rate for lo-fi effects",
      "type" : "effect chain"
   },
   "boundstopulse" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "input" : "the slider to check bounds on"
      },
      "description" : "sends a pulse when its input slider hits its max or min limit",
      "type" : "pulse"
   },
   "buffershuffler" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "fourtet" : "use a textural trick I saw four tet illustrate in a video once: slice the audio into chunks, and for each chunk it at double speed followed by playing it in reverse at double speed. this slider adjusts the mix between the original audio and this \"fourtetified\" audio.",
         "fourtetslices" : "chunk size to use for \"fourtet\" effect",
         "freeze input" : "retain the current buffer, without writing in new input",
         "grid" : "patch a grid in here from a \"midicontroller\" module",
         "interval" : "slice size",
         "num bars" : "number of bars to capture",
         "playback style" : "how to play clicked slices. or, with input notes, velocity range determines playback style."
      },
      "description" : "use notes to play back slices of a constantly-recording live input buffer. input notes trigger slices, with the pitch mapping to slice index. you can also click with a mouse to trigger slices.",
      "type" : "audio effects"
   },
   "butterworth" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "F" : "frequency cutoff",
         "Q" : "resonance"
      },
      "description" : "filter using the butterworth formula",
      "type" : "effect chain"
   },
   "capo" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "capo" : "number of semitones to shift",
         "diatonic" : "should we keep transposed notes in the scale?",
         "retrigger" : "immediately replay current notes when changing the capo amount"
      },
      "description" : "shifts incoming notes by semitones",
      "type" : "note effects"
   },
   "chorddisplayer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "display which chord is playing, in the context of the current scale",
      "type" : "note effects"
   },
   "chorder" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "chord" : "chord presets",
         "diatonic" : "should the grid be chromatic, or locked to the scale only?",
         "inversion" : "inversion presets"
      },
      "description" : "takes an incoming pitch and plays additional notes to form chords",
      "type" : "note effects"
   },
   "chordholder" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "pulse to play" : "when enabled, input notes aren't played immediately, but instead wait for an input pulse before playing",
         "stop" : "stop notes from playing"
      },
      "description" : "keeps any notes pressed at the same time sustaining, until new notes are pressed",
      "type" : "note effects"
   },
   "circlesequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "length*" : "number of steps in this ring",
         "note*" : "pitch to use for this ring",
         "offset*" : "timing offset for this ring"
      },
      "description" : "polyrhythmic sequencer that displays a loop as a circle",
      "type" : "instruments"
   },
   "clockin" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "device" : "device to receive from",
         "rounding" : "precision to round incoming tempo data",
         "smoothing" : "how much to smooth incoming tempo",
         "start offset ms" : "offset in milliseconds to tweak synchronization between bespoke and gear"
      },
      "description" : "reads in clock pulses from external midi devices to control bespoke's transport",
      "type" : "other"
   },
   "clockout" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "device" : "device to target",
         "multiplier" : "tempo multiplier for how the gear should respond to the signals",
         "send start" : "send a signal to reset the gear to the start of its sequence"
      },
      "description" : "sends out clock pulses to synchronize external midi devices",
      "type" : "other"
   },
   "comment" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "comment" : "type text here"
      },
      "description" : "a box to display some text, to explain a section of a patch",
      "type" : "other"
   },
   "compressor" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "attack" : "speed to apply gain reduction",
         "drive" : "rescale input to affect how much compression affects it",
         "lookahead" : "how much time to \"look ahead\" to adjust the compression envelope. this necessarily introduces a delay into your output, which could be compensated for by running sequencers slightly early.",
         "mix" : "amount of compression. lower this value for a \"parallel compression\" effect. you should use this mix slider instead of the effectchain's mix slider, to compensate for lookahead.",
         "output" : "makeup gain, to increase volume",
         "ratio" : "how much gain reduction to apply when the single passes the threshold",
         "release" : "speed to remove gain reduction",
         "threshold" : "threshold where gain should start to be reduced"
      },
      "description" : "try to keep volume at a certain level",
      "type" : "effect chain"
   },
   "controlrecorder" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "clear" : "clear the recording",
         "length" : "the interval to quantize to",
         "quantize" : "should we quantize playback to a specified rhythmic interval?",
         "record" : "should we be recording input? playback starts after the recording is complete",
         "speed" : "speed up or slow down playback"
      },
      "description" : "record and play back changes made to a control",
      "type" : "modulators"
   },
   "controlsequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "interval" : "rate to advance",
         "length" : "length of the sequence",
         "random" : "randomize sequence values",
         "record" : "record targeted value to steps",
         "step *" : "value for this step"
      },
      "description" : "modulate a control step-wise at an interval",
      "type" : "modulators"
   },
   "curve" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "input" : "input value (intended as a modulation target)"
      },
      "description" : "remap an input over its range with a curve. double-click on the curve to add points, right click on points to remove them, drag on lines to bend them.",
      "type" : "modulators"
   },
   "curvelooper" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "length" : "length of the loop",
         "randomize" : "create a random curve"
      },
      "description" : "modulate a value over time with a looping curve",
      "type" : "modulators"
   },
   "dataprovider" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "interval" : "the interval to measure",
         "realtime" : "if enabled this module will work on the audio thread which is more accurate but also more resource intense",
         "set" : "click here to send the value (or, send a pulse to this module for the same result)",
         "type" : "the type of value to provide"
      },
      "description" : "provides modulation values normally not easily accessible.",
      "type" : "modulators"
   },
   "dcoffset" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "offset" : "amount of offset to add"
      },
      "description" : "add a constant offset to an audio signal",
      "type" : "audio effects"
   },
   "dcremover" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "description" : "high pass filter with a 10hz cutoff to remove DC offset, to keep signal from drifting away from zero",
      "type" : "effect chain"
   },
   "delay" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "amount" : "amount of delay that returns",
         "delay" : "delay in milliseconds",
         "dry" : "should the dry signal pass through, or just the delayed signal?",
         "feedback" : "should the output audio feed back into the delay?",
         "input" : "should we accept input into the delay?",
         "interval" : "sets delay length to a musical duration",
         "invert" : "should the delayed audio have its signal inverted? this can give a different sound, and also cancel out DC offset to prevent it from accumulating with feedback.",
         "short" : "shortcut to shrink the range of the delay slider, to allow for audible-rate delays and comb filter sounds"
      },
      "description" : "echoing delay",
      "type" : "effect chain"
   },
   "distortion" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "center input" : "remove dc offset from input signal to distort in a more controlled way",
         "clip" : "cutoff point of distortion, lower values result in more extreme distortion",
         "fuzz" : "push input signal off-center to distort asymmetrically",
         "preamp" : "signal gain before feeding into distortion",
         "type" : "style of distortion to apply"
      },
      "description" : "waveshaping distortion",
      "type" : "effect chain"
   },
   "dotsequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "clear" : "clear the contents of the dot grid",
         "cols" : "number of columns",
         "dotgrid" : "the dot grid",
         "double" : "double the length of this sequence",
         "interval" : "rate to play notes at",
         "notemode" : "which set of pitches should the rows represent?",
         "octave" : "octave of the bottom pitch of this sequence",
         "row offset" : "amount to offset the mapping of row to pitch",
         "rows" : "number of rows"
      },
      "description" : "polyphonic note sequencer with adjustable note length and velocity. click and drag horizontally to adjust length. click and drag vertically to adjust the velocity. hover and use the arrow keys to move dots. hover and use the mouse wheel to tweak dot lengths.",
      "type" : "instruments"
   },
   "drumplayer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "aud" : "scroll to audition samples in the current pad's head category, or a directory last dropped onto a pad",
         "edit" : "show pads for editing",
         "envelope *" : "should we apply a volume envelope to the sample?",
         "envelopedisplay *" : "[none]",
         "envelopedisplay *A" : "envelope attack",
         "envelopedisplay *D" : "envelope decay",
         "envelopedisplay *R" : "envelope release",
         "envelopedisplay *S" : "envelope sustain",
         "full vel" : "always play drum hits at full velocity",
         "grab *" : "grab this sample",
         "grid" : "patch a grid in here from a \"midicontroller\" module",
         "hitcategory*" : "folder to choose from, when clicking the \"random\" button. these folders are found in the data/drums/hits/ directory",
         "kit" : "[none]",
         "linkid *" : "if linkid is not -1, silence any other sample with a matching linkid (useful for linking open and closed hats)",
         "mono" : "force output to mono",
         "next *" : "choose the next sample from the selected hitcategory",
         "pan *" : "stereo pan position of sample",
         "prev *" : "choose the previous sample from the selected hitcategory",
         "quantize" : "quantize input to this interval",
         "random *" : "choose a random sample from the selected hitcategory",
         "repeat" : "if quantizing, should held notes repeat at that interval?",
         "shuffle" : "random is samples, speeds, and pans",
         "single out *" : "should the sample have its own individual output?",
         "single voice" : "only play a single drum hit at once, choking all others out (as if they all shared the same linkid)",
         "speed" : "global sample speed multiplier",
         "speed *" : "speed of sample",
         "speed rnd" : "global sample speed randomization amount",
         "start *" : "start offset percentage of sample",
         "test *" : "play this sample",
         "view ms *" : "envelope view length in milliseconds",
         "vol" : "the output volume",
         "vol *" : "volume of sample ",
         "widen *" : "stereo delay of sample to create width"
      },
      "description" : "sample player intended for drum playback",
      "type" : "synths"
   },
   "drumsequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "<" : "shift whole pattern one step earlier",
         ">" : "shift whole pattern one step later",
         "clear" : "clear sequence",
         "column" : "current column, to use for visualizing the step on a midi controller",
         "grid" : "patch a grid in here from a \"midicontroller\" module",
         "measures" : "length of the sequence in measures",
         "metastep" : "patch a grid in here from a \"midicontroller\" module to control the \"meta step\". I forget what this does. oops.",
         "offset*" : "shift row forward/backward in time. try making your snares a little early, your hats a little late, etc.",
         "offsets" : "show \"offsets\" sliders",
         "r amt" : "the chance that each step will change when being randomized. low values will only change a small amount of the sequence, high values will replace more of the sequence.",
         "r den" : "density of the randomizer output. the higher this is, the busier the random output will be.",
         "r lock*" : "lock this row so it doesn't get randomized",
         "random*" : "randomize this row",
         "randomize" : "randomize the sequence",
         "repeat" : "repeat input notes at this rate",
         "rowpitch*" : "output pitch for this row",
         "step" : "length of each step",
         "vel" : "velocity to use when setting a step",
         "velocity" : "patch a grid in here from a \"midicontroller\" module to control the velocity",
         "velocitytype" : "velocity to use when setting a step",
         "yoff" : "vertical offset for grid controller's view of the pattern"
      },
      "description" : "step sequencer intended for drums. hold shift when dragging on the grid to adjust step velocity, or hover over a step and press the up and down arrow keys to adjust velocity.",
      "type" : "instruments"
   },
   "drumsynth" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "adsrfilter*" : "",
         "adsrfilter*A" : "",
         "adsrfilter*D" : "",
         "adsrfilter*R" : "",
         "adsrfilter*S" : "",
         "adsrfreq*" : "",
         "adsrfreq*A" : "",
         "adsrfreq*D" : "",
         "adsrfreq*R" : "",
         "adsrfreq*S" : "",
         "adsrnoise*" : "",
         "adsrnoise*A" : "",
         "adsrnoise*D" : "",
         "adsrnoise*R" : "",
         "adsrnoise*S" : "",
         "adsrtone*" : "",
         "adsrtone*A" : "",
         "adsrtone*D" : "",
         "adsrtone*R" : "",
         "adsrtone*S" : "",
         "cutoffmax*" : "filter start cutoff frequency",
         "cutoffmin*" : "filter end cutoff frequency",
         "edit" : "display parameters for each hit",
         "freqmax*" : "oscillator start frequency",
         "freqmin*" : "oscillator end frequency",
         "noise*" : "noise volume",
         "oversampling" : "oversampling amount. increases sound quality, but also increases cpu usage.",
         "q*" : "filter resonance",
         "type*" : "oscillator type",
         "vol" : "the output volume",
         "vol*" : "oscillator volume"
      },
      "description" : "oscillator+noise drum synth",
      "type" : "synths"
   },
   "effectchain" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "<" : "move this effect to earlier in the chain",
         ">" : "move this effect to later in the chain",
         "effect" : "select which effect to add",
         "exit effect" : "on push2, back effect control out to the main effectchain controls",
         "mix*" : "wet/dry slider for this effect",
         "spawn" : "spawn the currently highlighted effect",
         "volume" : "output gain",
         "x" : "delete this effect"
      },
      "description" : "container to hold a list of effects, applied in series. the effects can be easily reordered with the < and > buttons, and deleted with the x button. hold shift to expose a x button for all effects.",
      "type" : "audio effects"
   },
   "envelope" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "adsr" : "envelope view",
         "adsrA" : "envelope attack",
         "adsrD" : "envelope decay",
         "adsrR" : "envelope release",
         "adsrS" : "envelope sustain",
         "advanced" : "switch to advanced envelope editor (allows for a more complicated envelope than just an ADSR). double-click on an advanced envelope line to add stages, right click on points to remove them, drag on lines to bend them.",
         "has sustain" : "should this envelope have a sustain stage?",
         "high" : "output high value",
         "length" : "length of envelope display",
         "low" : "output low value",
         "max sustain" : "what's the maximum length of the sustain, in milliseconds? a value of -1 indicates no maximum",
         "sustain stage" : "which step of the envelope should have the sustain?",
         "use velocity" : "should envelope output be scaled by input velocity?"
      },
      "description" : "modulate a value with a triggered envelope",
      "type" : "modulators"
   },
   "eq" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "enabled*" : "enable this band?",
         "f*" : "frequency cutoff for this band",
         "g*" : "gain for this band",
         "q*" : "resonance for this band",
         "type*" : "what type of filter should this band use"
      },
      "description" : "multi-band equalizer, to adjust output levels at frequency ranges",
      "type" : "audio effects"
   },
   "euclideansequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "clear" : "clear all steps, onsets, rotation and offset in all rings",
         "note" : "randomize notes in all rings",
         "note chance" : "what is the chance a note gets changed",
         "note*" : "pitch to use for this ring",
         "o *" : "in what range is offset created",
         "oct*" : "in what octave range are notes created",
         "offset" : "randomize offset in all rings",
         "offset chance" : "what is the chance that an offset gets changed",
         "offset*" : "timing offset for this ring",
         "ons *" : "in what range are onsets created",
         "onset chance" : "what is the chance that an onset gets changed",
         "onsets" : "randomize onsets in all rings",
         "onsets*" : "number of onsets in this ring",
         "random" : "randomize all steps, onsets and rotation in all rings",
         "random*" : "randomize steps, onsets and rotation in this ring",
         "rot chance" : "what is the chance that rotation gets changed",
         "rot hi" : "in what range is rotation created",
         "rot lo" : "in what range is rotation created",
         "rotation" : "randomize rotation in all rings",
         "rotation*" : "rotation of this ring",
         "step chance" : "what is the chance a step gets changed",
         "steps" : "randomize steps in all rings",
         "steps*" : "number of steps in this ring",
         "stp*" : "in what range are steps created"
      },
      "description" : "euclidean sequencer displays a loop as a circle. the notes are calculated using the euclidean rhythm algorithm.",
      "type" : "instruments"
   },
   "eventcanvas" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "canvas" : "canvas of events. canvas controls:\n-shift-click to add an event\n-hold shift and drag an event to duplicate\n-hold alt to drag an event without snapping\n-hold ctrl while dragging to snap to an interval\n-hold shift and scroll to zoom\n-hold alt and grab empty space to move slide the canvas view\n-hold ctrl and grab empty space to zoom the canvas view",
         "clear" : "delete all elements",
         "delete" : "delete highlighted elements",
         "drag mode" : "direction that elements can be dragged",
         "interval" : "grid for snapping events to",
         "measures" : "length of loop",
         "quantize" : "quantizes events to grid",
         "record" : "record connected values as they change",
         "scrollh" : "horizontal scrollbar",
         "timeline" : "control loop points",
         "view rows" : "number of visible rows"
      },
      "description" : "schedule values to set over time",
      "type" : "other"
   },
   "expression" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "a" : "variable to use in expressions",
         "b" : "variable to use in expressions",
         "c" : "variable to use in expressions",
         "d" : "variable to use in expressions",
         "e" : "variable to use in expressions",
         "input" : "input to use as x variable",
         "y=" : "expression to modify input. try something like \"x+sin(x*pi*a)\". available variables: a,b,c,d,e = the sliders below. t = time."
      },
      "description" : "shape modulation with a text-based mathematical expression",
      "type" : "modulators"
   },
   "feedback" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "limit" : "clip the feedback audio to this range, to avoid issues with feedback blowing out too intensely."
      },
      "description" : "feed delayed audio back into earlier in the signal chain. use the \"feedback out\" connector for sending the audio back up the chain, and the primary output connector for sending the resulting audio forward. using feedback can often lead to extreme and difficult-to-control results!",
      "type" : "audio effects"
   },
   "fftvocoder" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "carrier" : "carrier signal gain",
         "cut" : "how many bass partials to remove",
         "dry/wet" : "how much original input vs vocoded signal to output",
         "fric thresh" : "fricative detection sensitivity, to switch between using the carrier signal and white noise for vocoding",
         "input" : "input signal gain",
         "phase off" : "how much we should offset the phase of the carrier signal's partials",
         "volume" : "output gain",
         "whisper" : "how much the carrier signal partial's phases should be randomized, which affects how whispery the output sound is"
      },
      "description" : "FFT-based vocoder",
      "type" : "audio effects"
   },
   "fmsynth" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "adsrharm" : "",
         "adsrharm2" : "",
         "adsrharm2A" : "",
         "adsrharm2D" : "",
         "adsrharm2R" : "",
         "adsrharm2S" : "",
         "adsrharmA" : "",
         "adsrharmD" : "",
         "adsrharmR" : "",
         "adsrharmS" : "",
         "adsrmod" : "",
         "adsrmod2" : "",
         "adsrmod2A" : "",
         "adsrmod2D" : "",
         "adsrmod2R" : "",
         "adsrmod2S" : "",
         "adsrmodA" : "",
         "adsrmodD" : "",
         "adsrmodR" : "",
         "adsrmodS" : "",
         "adsrosc" : "",
         "adsroscA" : "",
         "adsroscD" : "",
         "adsroscR" : "",
         "adsroscS" : "",
         "harmratio" : "harmonic ratio of first-order modulator to input pitch",
         "harmratio2" : "harmonic ratio of second-order modulator to input pitch",
         "mod" : "amount to modulate first-order modulator",
         "mod2" : "amount to modulate second-order modulator",
         "phase0" : "phase offset for base oscillator",
         "phase1" : "phase offset for first-order modulator",
         "phase2" : "phase offset for second-order modulator",
         "tweak" : "multiplier to harmonic ratio for first-order modulator",
         "tweak2" : "multiplier to harmonic ratio for second-order modulator",
         "vol" : "the output volume"
      },
      "description" : "polyphonic fm synthesis",
      "type" : "synths"
   },
   "formant" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "a" : "[todo]",
         "e" : "[todo]",
         "ee" : "[todo]",
         "i" : "[todo]",
         "oo" : "[todo]",
         "u" : "[todo]"
      },
      "description" : "[unfinished, broken]filter focused on controlling formants",
      "type" : "unknown"
   },
   "fouronthefloor" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "two" : "sends note only every two beats"
      },
      "description" : "sends note 0 every beat, to trigger a kick drum",
      "type" : "instruments"
   },
   "freeverb" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "damp" : "high frequency attenuation; a value of zero means all frequencies decay at the same rate, while higher settings will result in a faster decay of the high frequency range",
         "dry" : "amount of untouched signal",
         "room size" : "controls the length of the reverb, a higher value means longer reverb",
         "wet" : "amount of reverb signal",
         "width" : "stereo width of reverb"
      },
      "description" : "reverb using the \"freeverb\" algorithm",
      "type" : "effect chain"
   },
   "freqdelay" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "dry/wet" : "how much of the effect to apply"
      },
      "description" : "delay effect with delay length based upon input notes",
      "type" : "audio effects"
   },
   "fubble" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "clear" : "clear the drawing",
         "length" : "the interval to quantize to",
         "mutate amount" : "amount to affect drawing by perlin noise field",
         "mutate noise" : "rate to move through perlin noise field",
         "mutate warp" : "scale of perlin noise field",
         "quantize" : "should we quantize playback to a specified rhythmic interval?",
         "reseed" : "jump to a different location in the perlin noise field",
         "speed" : "speed up or slow down playback"
      },
      "description" : "draw on an X/Y pad and replay the drawing to modulate values. based on a concept proposed by olivia jack",
      "type" : "modulators"
   },
   "gain" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "gain" : "amount to adjust signal. a value of 1 will cause no change to the signal."
      },
      "description" : "adjusts volume of audio signal",
      "type" : "audio effects"
   },
   "gainstage" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "gain" : "volume multiplier"
      },
      "description" : "control volume within an effectchain",
      "type" : "effect chain"
   },
   "gate" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "attack" : "speed at which gate blends open",
         "release" : "speed at which gate blends closed",
         "threshold" : "volume threshold to open up the gate"
      },
      "description" : "only allow signal in when it's above a certain threshold. useful to eliminate line noise, or just as an effect.",
      "type" : "effect chain"
   },
   "globalcontrols" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "background b" : "amount of blue in background color",
         "background g" : "amount of green in background color",
         "background r" : "amount of red in background color",
         "cable alpha" : "opacity of the cables",
         "corner radius" : "how round bespoke's rectangles are",
         "lissajous b" : "amount of blue in background lissajous curve",
         "lissajous g" : "amount of green in background lissajous curve",
         "lissajous r" : "amount of red in background lissajous curve",
         "scroll x" : "emulate horizontal mouse scrolling",
         "scroll y" : "emulate vertical mouse scrolling",
         "x pos" : "horizontal panning position",
         "y pos" : "vertical panning position",
         "zoom" : "zoom level"
      },
      "description" : "interface controls, intended to allow you to use midi controllers to navigate the canvas. controlling these sliders directly with the mouse is not recommended.",
      "type" : "other"
   },
   "granulator" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "autocapture" : "freeze input at this interval",
         "dry" : "amount of dry signal to allow through",
         "frz" : "freeze the current recorded buffer",
         "g oct" : "should we add octaves and fifths?",
         "len ms" : "length of each grain in milliseconds",
         "overlap" : "number of overlapping grains",
         "pos" : "playback position within the buffer",
         "pos r" : "randomization of grain start point",
         "spa r" : "randomization of time between grains",
         "spd r" : "randomization of grain speed",
         "speed" : "speed of grain playback",
         "width" : "stereo width of grain placement"
      },
      "description" : "granulate live input",
      "type" : "effect chain"
   },
   "gravity" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "drag" : "the resistance force to apply opposite the velocity",
         "gravity" : "the gravitational force to apply downwards",
         "kick" : "click to apply kick force (or, pulse this module for the same result)",
         "kick amt" : "the amount of upward force to apply when kicking"
      },
      "description" : "make a modulation value rise and fall with physics",
      "type" : "modulators"
   },
   "grid" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "grid" : "patch a grid in here, from a \"midicontroller\" module",
         "momentary" : "should clicks be treated as momentary inputs?"
      },
      "description" : "generic grid, to be used by \"script\" module, to assist in writing scripts that use grid-based midi controllers",
      "type" : "other"
   },
   "gridkeyboard" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "arrangement" : "what style of layout should we use?",
         "ch.latch" : "latch chord button presses",
         "grid" : "patch a grid in here from a \"midicontroller\" module",
         "latch" : "latch key presses, so you press once to play a note, and press again to release a note",
         "layout" : "keyboard style",
         "octave" : "base octave",
         "p.root" : "for chorder, make root note always play"
      },
      "description" : "grid-based keyboard, intended primarily for 64-pad grid controllers",
      "type" : "instruments"
   },
   "gridnotedisplayer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "use with a gridkeyboard to display currently playing notes, to visualize chords, arpeggiation, etc.",
      "type" : "note effects"
   },
   "gridsliders" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "direction" : "should the grid display the sliders vertically, or horizontally?",
         "grid" : "patch a grid in here from a \"midicontroller\" module"
      },
      "description" : "use a grid controller to control multiple sliders",
      "type" : "modulators"
   },
   "groupcontrol" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "group enabled" : "controls the connected checkboxes"
      },
      "description" : "connect to several checkboxes, and control them all with one checkbox",
      "type" : "other"
   },
   "helpdisplay" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "copy build info" : "copy info about this build to the clipboard, for help requests",
         "help page" : "which page of help information to show",
         "show tooltips" : "displays these tooltips. you can also toggle them with the F1 key, and you can turn these on or off by default in the \"settings\" menu."
      },
      "description" : "displays help information",
      "type" : "unknown"
   },
   "input" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "ch" : "which channel (or channels, if you want stereo) to use"
      },
      "description" : "get audio from input source, like a microphone",
      "type" : "audio effects"
   },
   "inverter" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "description" : "multiply a signal by -1. enables some pretty interesting effects when used with sends, to subtract out parts of signals when recombined.",
      "type" : "audio effects"
   },
   "karplusstrong" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "feedback" : "amount of feedback for resonance",
         "filter" : "amount to filter resonance",
         "invert" : "should the feedback invert?",
         "lite cpu" : "only recalculate some parameters once per buffer, to reduce CPU load. can make pitch bends and rapid modulation sound worse in some scenarios.",
         "pitchtone" : "adjust how pitch influences filter amount. a value of zero gives even filtering across the entire pitch range, higher values filter high pitches less, low values filter low pitches less.",
         "source type" : "audio to use for excitation",
         "vel2env" : "how much velocity should affect excitation attack time",
         "vel2vol" : "how much velocity should affect voice volume",
         "vol" : "output volume",
         "x att" : "fade in time for excitation audio",
         "x dec" : "fade out time for excitation audio",
         "x freq" : "frequency of excitation audio"
      },
      "description" : "polyphonic plucked string physical modeling synth",
      "type" : "synths"
   },
   "keyboarddisplay" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "displays input notes on a keyboard, and allows you to click the keyboard to create notes",
      "type" : "instruments"
   },
   "label" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "color" : "The color of the label",
         "font" : "The font of the label",
         "label" : "The label that will be displayed",
         "showcontrols" : "Hide and show the controls to modify the label",
         "size" : "The font size of the label"
      },
      "description" : "A module to display a label, helpful in marking what is where in large patches",
      "type" : "other"
   },
   "leveltocv" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "attack" : "rise to the input level at this rate",
         "gain" : "multiply the input audio by this value",
         "max" : "output when level is one",
         "min" : "output when level is zero",
         "release" : "decay from the input level at this rate"
      },
      "description" : "output a modulation value based on the level of incoming audio",
      "type" : "modulators"
   },
   "lfo" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "bias" : "bias the waveform towards the low or high point",
         "enable" : "turn on/off modulation",
         "free rate" : "rate of oscillator running in non-clock-synced time",
         "high" : "output value at waveform's high point",
         "interval" : "length of oscillation period",
         "length" : "proportion of time that should be spent on the waveform cycle",
         "lite cpu" : "only recalculate some parameters once per buffer, to reduce CPU load. can sound worse in some scenarios, especially with rapid modulation.",
         "low" : "output value at waveform's low point",
         "offset" : "phase offset, to make oscillation earlier/later",
         "osc" : "type of oscillation waveform",
         "pin" : "make LFO window remain visible",
         "shuffle" : "adjust the waveoform to have a fast and slow cycle",
         "soften" : "smooth out the hard edges of square and saw waveforms",
         "spread" : "spread the waveform out to be closer to the low and high points"
      },
      "description" : "modulates a slider with a low-frequency oscillator",
      "type" : "modulators"
   },
   "linnstrumentcontrol" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "blackout" : "turn off all lights",
         "controller" : "midicontroller with the linnstrument",
         "decay" : "amount of time it takes for lit key to die off",
         "guitar lines" : "should we use the \"guitar lines\" light layout?",
         "octaves" : "when pressing a key, should we light that key for all octaves?"
      },
      "description" : "[work in progress]control the lights of a linnstrument controller in various ways",
      "type" : "note effects"
   },
   "lissajous" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "scale" : "visual scale of lissajous image"
      },
      "description" : "draw input audio as a lissajous curve. turn off \"autocorrelation\" in the module's triangle menu to use stereo channels to show stereo width.",
      "type" : "audio effects"
   },
   "looper" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         " m " : "take the contents of this looper and merge it into another. click this button on the merge source, then on the merge target.",
         ".5x" : "make loop play at half speed",
         "2x" : "make loop play at double speed",
         "apply" : "shift the contents of the looper so the current offset is the start of the buffer",
         "auto" : "should pitch shift auto-adjust as the transport tempo adjusts?",
         "b" : "bake current volume into waveform",
         "beatwheel depth left" : "[none]",
         "beatwheel depth right" : "[none]",
         "beatwheel on" : "[none]",
         "beatwheel pos left" : "[none]",
         "beatwheel pos right" : "[none]",
         "beatwheel single measure" : "[none]",
         "capture" : "when the next loop begins, record input for the duration of the loop",
         "clear" : "clear the loop audio",
         "commit" : "commit the current looperrecorder buffer to this loop",
         "copy" : "take the contents of this looper and copy it onto another. click this button on the copy source, then on the copy target.",
         "decay" : "amount to lower volume each loop",
         "extend" : "make loop twice as long",
         "fourtet" : "use a textural trick I saw four tet illustrate in a video once: slice the audio into chunks, and for each chunk it at double speed followed by playing it in reverse at double speed. this slider adjusts the mix between the original audio and this \"fourtetified\" audio.",
         "fourtetslices" : "chunk size to use for \"fourtet\" effect",
         "mute" : "silence this looper",
         "num bars" : "loop length in measures",
         "offset" : "amount to offset looper's playhead from transport position",
         "passthrough" : "should we pass incoming audio through to the output? turn off to mute incoming audio.",
         "pitch" : "amount to pitch shift looper output",
         "resample for tempo" : "this button appears when the current global tempo no longer matches the tempo that the buffer was recorded at. click this to resample the buffer to match the new tempo.",
         "save" : "save this loop to a wav file",
         "scr" : "allow loop to be scratched by adjusting \"scrspd\"",
         "scrspd" : "playback speed, used with \"scr\" is enabled. modulate quickly for a vinyl-like scratching effect.",
         "swap" : "swap the contents of this looper and with another. click this button on two loopers to swap them.",
         "undo" : "undo last loop commit",
         "volume" : "output volume",
         "write" : "write input audio to loop buffer"
      },
      "description" : "loop input audio. use with a \"looperrecorder\" for full functionality.",
      "type" : "audio effects"
   },
   "loopergranulator" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "freeze" : "stop advancing looper time",
         "len ms" : "length of each grain in milliseconds",
         "loop pos" : "playback position within loop",
         "octaves" : "should we add octaves and fifths?",
         "on" : "use granular synthesis for looper playback",
         "overlap" : "number of overlapping grains",
         "pos rand" : "randomization of grain start point",
         "spacing rand" : "randomization of time between grains",
         "speed" : "speed of grain playback",
         "speed rand" : "randomization of grain speed",
         "width" : "stereo width of grain placement"
      },
      "description" : "use with a \"looper\" module to play the contents with granular synthesis",
      "type" : "other"
   },
   "looperrecorder" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         ".5tempo" : "halve global transport tempo, while keeping connected loopers sounding the same",
         "1" : "capture the last measure to the currently-targeted looper",
         "2" : "capture the last 2 measures to the currently-targeted looper",
         "2xtempo" : "double global transport tempo, while keeping connected loopers sounding the same",
         "4" : "capture the last 4 measures to the currently-targeted looper",
         "8" : "capture the last 8 measures to the currently-targeted looper",
         "auto-advance" : "automatically advance to the next looper when committing",
         "cancel free rec" : "if \"free rec\" is enabled, cancel recording without setting the loop length",
         "clear" : "clear the recorded buffer",
         "free rec" : "enable to start recording a loop with no predetermined length. disable to end recording, adjust global transport to match the loop length, and switch the recorder's mode to \"loop\"",
         "length" : "length in measures to use when connected loopers use the \"commit\" button",
         "mode" : "recorder mode: use \"record\" to record input and allow it to be committed to buffers when you're ready to loop, use \"overdub\" to record input and play the loop at our specified length, and use \"loop\" to play the current loop without adding input",
         "orig speed" : "reset looper to tempo that loops were recorded at",
         "resample" : "resample all connected loopers to new tempo",
         "resample & set key" : "snap tempo to nearest value that matches a key (based upon the current key and the tempo change), resample all connected loopers to that new tempo, and change global scale to the new key",
         "snap to pitch" : "snap tempo to nearest value that matches a key",
         "target" : "looper to commit audio to when using the on-buffer capture buttons to the left",
         "write*" : "writes to this looper, with a loop length matching the nearest power of 2 (1, 2, 4, 8, etc) of how long this checkbox was enabled"
      },
      "description" : "command center to manage recording into multiple loopers, and allow retroactive loop capture (i.e., always-on recording)",
      "type" : "audio effects"
   },
   "looperrewriter" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "go" : "rewrite the connected looper, and if that looper is connected to a send, set that send to output only to the right outlet",
         "new loop" : "start recording a dynamic loop length. press \"go\" when you want to rewrite it to the looper. this will also change bespoke's global tempo to match this new loop, so it's quite powerful and scary! click it again to cancel."
      },
      "description" : "rewrites the contents of a looper with received input, to help you resample your own loops. attach the grey dot to a \"looper\" module.\n\nthe ideal way to use this module is to hook the \"looper\" directly up to a \"send\", hook the leftmost outlet of the \"send\" up to your effects processing (like an \"effectchain\"), hook the effect processing up to this \"rewriter\", and then also connect the rightmost outlet of the \"send\" up to this \"rewriter\"",
      "type" : "audio effects"
   },
   "loopstorer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "clear" : "[todo]",
         "quantization" : "[todo]",
         "rewrite" : "[todo]",
         "select *" : "[todo]"
      },
      "description" : "[abandoned module, probably broken]store a looper's loops to swap them in and out",
      "type" : "unknown"
   },
   "m185sequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "gate*" : "behavior for each row: \"repeat\" plays every step, \"once\" plays just the first step, \"hold\" holds across all steps, \"rest\" plays no steps",
         "interval" : "interval per step",
         "pitch*" : "pitch to use for this row",
         "pulses*" : "number of steps this row should last",
         "reset step" : "resets counter to first step"
      },
      "description" : "sequencer using the unique paradigm of the m185 or intellijel metropolis",
      "type" : "instruments"
   },
   "macroslider" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "end*" : "the output value at the top of the input's range",
         "input" : "the input value. intended to be a modulation patch target.",
         "start*" : "the output value at the bottom of the input's range"
      },
      "description" : "take a value and send scaled versions of that value to multiple destinations",
      "type" : "modulators"
   },
   "metronome" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "vol" : "metronome volume"
      },
      "description" : "beeps to the beat",
      "type" : "synths"
   },
   "midicc" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "control" : "CC control number",
         "value" : "outputs a CC value when this changes"
      },
      "description" : "outputs midi control change messages to route to a \"midioutput\" module",
      "type" : "note effects"
   },
   "midicontroller" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         " x " : "delete this connection",
         "14bit" : "is this a 14-bit midi control, with this control as the LSB and the control 32 less than this as the MSB?",
         "add" : "add a mapping manually",
         "bind (hold shift)" : "when this is enabled, you can map a midi input to a UI control by hovering over a UI control, holding shift, and then using desired midi input",
         "blink" : "when the targeted control is enabled, send alternating on/off messages, to blink the associated LED",
         "channel" : "which channel to pay attention to",
         "control" : "pitch or control to refer to",
         "controller" : "midi device to use",
         "controltype" : "how this control should modify the target.\n -slider: set the value interpolated between \"midi off\" and \"midi on\" to the slider's value\n -set: set the specified value directly when this button is pressed\n -release: set the specified value directly when this button is released\n -toggle: toggle the control's value to on/off when this button is pressed\n -direct: set the control to the literal midi input value",
         "copy" : "duplicate this connection",
         "feedback" : "which cc or note should we send the feedback to?",
         "increment" : "when \"controltype\" is \"set\" or \"release\", the targeted control is incremented by this amount (and the \"value\" field is ignored). when \"controltype\" is \"slider\", the targeted control is changed by this amount in the direction the control was changed (this setting is useful for \"infinite encoders\")",
         "layout" : "which layout file should we use for this controller? these can be created in your Documents/BespokeSynth/controllers folder.",
         "mappingdisplay" : "which mapping view to see",
         "messagetype" : "type of midi message",
         "midi off" : "the lower end of the midi range. send this value when the targeted control is off. if \"scale\" is enabled, this also controls the lower end of the slider range, and you can set midi off to be higher than midi on to reverse a slider's direction.",
         "midi on" : "the upper end of the midi range. send this value when the targeted control is on. if \"scale\" is enabled, this also controls the upper end of the slider range, and you can set midi off to be higher than midi on to reverse a slider's direction.",
         "monome" : "which monome should we use?",
         "osc input port" : "port to use for osccontroller input",
         "page" : "select which page of midi controls to use. each page acts like an independent midi controller, so you can use pages to allow one midi controller to switch between controlling many things",
         "pageless" : "should this connection work across all pages of the midicontroller?",
         "path" : "path to the control that should be affected. you can also enter \"hover\" here, to affect whichever control the mouse is hovering over.",
         "scale" : "should the output of this midi slider be scaled between \"midi off\" and \"midi on\"?",
         "twoway" : "should we send feedback to the controller? (to control the LEDs associated with the button/knob)",
         "value" : "the value to set"
      },
      "description" : "get midi input from external devices. to get a nice display in the \"layout\" view, create a .json file with the same name as your controller to describe your controller's layout, and place it in your \"data/controllers\" directory. look at the other files in that directory for examples.",
      "type" : "instruments"
   },
   "midioutput" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "controller" : "where to send midi to"
      },
      "description" : "send midi to an external destination, such as hardware or other software",
      "type" : "note effects"
   },
   "modulationvizualizer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "display MPE modulation values for notes",
      "type" : "note effects"
   },
   "modwheel" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "modwheel" : "expression level"
      },
      "description" : "adds an expression value to a note",
      "type" : "note effects"
   },
   "modwheeltocv" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "max" : "output for modwheel value 127",
         "min" : "output for modwheel value 0"
      },
      "description" : "take a note's modwheel value and convert it to a modulation value",
      "type" : "modulators"
   },
   "modwheeltopressure" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "swaps expression input to midi pressure in the output",
      "type" : "note effects"
   },
   "modwheeltovibrato" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "vibinterval" : "rate of vibrato",
         "vibrato" : "amount of pitch bend"
      },
      "description" : "convert note mod wheel input rhythmic pitch bend",
      "type" : "note effects"
   },
   "mpesmoother" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "modwheel" : "amount to smooth incoming modwheel",
         "pitch" : "amount to smooth incoming pitchbend",
         "pressure" : "amount to smooth incoming pressure"
      },
      "description" : "smooth out MPE parameters",
      "type" : "note effects"
   },
   "mpetweaker" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "modwheel mult" : "amount to multiply incoming modwheel",
         "modwheel offset" : "amount to offset incoming modwheel",
         "pitchbend mult" : "amount to multiply incoming pitchbend",
         "pitchbend offset" : "amount to offset incoming pitchbend",
         "pressure mult" : "amount to multiply incoming pressure",
         "pressure offset" : "amount to offset incoming pressure"
      },
      "description" : "adjust incoming MPE modulation values",
      "type" : "note effects"
   },
   "mult" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "value 1" : "",
         "value 2" : ""
      },
      "description" : "outputs the result of value 1 multiplier by value 2. value 1 and value 2 are intended to be patch targets for modulators.",
      "type" : "modulators"
   },
   "multitapdelay" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "delay *" : "tap delay time, in milliseconds",
         "display length" : "length of buffer display, in seconds",
         "dry" : "how much dry signal to allow through",
         "feedback *" : "how much delayed audio from this tap should feed back in to the input",
         "gain *" : "tap delay amount",
         "pan *" : "stereo pan for this tap"
      },
      "description" : "delay with multiple tap points",
      "type" : "audio effects"
   },
   "multitrackrecorder" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "add track" : "add an additional track",
         "bounce" : "write the tracks to your recordings directory",
         "clear" : "clear the audio in the tracks",
         "record" : "record input to the tracks"
      },
      "description" : "record several synchronized tracks of audio, to write to disk for mixing in an external DAW",
      "type" : "other"
   },
   "multitrackrecordertrack" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         " X " : "delete this track"
      },
      "description" : "a track in a multitrack recorder",
      "type" : "unknown"
   },
   "muter" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "ms" : "ramp time to mute/unmute signal",
         "pass" : "when true, the signal is allowed through"
      },
      "description" : "mute an incoming signal",
      "type" : "effect chain"
   },
   "newpatchconfirm" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "cancel" : "dismiss this",
         "confirm" : "clear everything and start fresh"
      },
      "description" : "",
      "type" : "unknown"
   },
   "noisify" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "amount" : "amount of noise to apply",
         "width" : "how frequently a new noise sample should be chosen"
      },
      "description" : "multiply input signal by white noise",
      "type" : "effect chain"
   },
   "notecanvas" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "canvas" : "canvas of notes. canvas controls:\n-shift-click to add a note\n-hold shift and drag a note to duplicate\n-hold alt to drag a note without snapping\n-hold ctrl while dragging to snap to an interval\n-hold shift and scroll to zoom\n-hold alt and grab empty space to move slide the canvas view\n-hold ctrl and grab empty space to zoom the canvas view",
         "clear" : "delete all elements",
         "delete" : "delete highlighted elements",
         "drag mode" : "direction that elements can be dragged",
         "free rec" : "enable record mode, and extend canvas if we reach the end",
         "interval" : "interval to quantize to",
         "load midi" : "import canvas contents from a midi file",
         "loadtrack" : "which track number to import when using \"load midi\"",
         "measures" : "loop length",
         "play" : "play notes on canvas",
         "quantize" : "quantize selected notes to interval",
         "rec" : "record input notes to canvas",
         "save midi" : "export canvas contents to a midi file",
         "scrollh" : "horizontal scrollbar",
         "scrollv" : "vertical scrollbar",
         "show chord intervals" : "show brackets to indicate chord relationships",
         "timeline" : "control loop points",
         "view rows" : "number of visible rows"
      },
      "description" : "looping note roll",
      "type" : "instruments"
   },
   "notechain" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "duration" : "duration of note, in measures",
         "next" : "interval until sending pulse",
         "pitch" : "pitch to play",
         "trigger" : "play note for this chain node",
         "velocity" : "velocity for note"
      },
      "description" : "trigger a note, followed by a pulse to trigger another note after a delay",
      "type" : "instruments"
   },
   "notechance" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "*" : "generate a new random seed",
         "<" : "go to previous seed",
         ">" : "go to next seed",
         "beat length" : "restart the deterministic random sequence at this interval",
         "chance" : "probability that a note is allowed",
         "deterministic" : "allow for randomness to be repeated over an interval",
         "seed" : "number that determines the random sequence"
      },
      "description" : "randomly allow notes through",
      "type" : "note effects"
   },
   "notecounter" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "*" : "generate a new random seed",
         "<" : "go to previous seed",
         ">" : "go to next seed",
         "beat length" : "length over which the random sequence should deterministically repeat",
         "div" : "measure division, when using \"div\" as the interval",
         "interval" : "rate to advance",
         "length" : "length of the sequence",
         "random" : "output random pitches within the range, rather than sequential",
         "seed" : "number that determines the random sequence",
         "start" : "pitch at the start of the sequence",
         "sync" : "if the output pitch should be synchronized to the global transport"
      },
      "description" : "advance through pitches sequentially. useful for driving the \"notesequencer\" or \"drumsequencer\" modules.",
      "type" : "instruments"
   },
   "notecreator" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "duration" : "note length when \"trigger\" button is used",
         "on" : "turn on to start note, turn off to end note",
         "pitch" : "output note pitch",
         "trigger" : "press to trigger note for specified duration",
         "velocity" : "note velocity"
      },
      "description" : "create a one-off note",
      "type" : "instruments"
   },
   "notedelayer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "delay" : "amount of time to delay, in measures"
      },
      "description" : "delay input notes by a specified amount",
      "type" : "note effects"
   },
   "notedisplayer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "show input note info",
      "type" : "note effects"
   },
   "noteduration" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "duration" : "length of the note in measures"
      },
      "description" : "sets the length a note will play, ignoring the note-off message",
      "type" : "note effects"
   },
   "noteecho" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "delay *" : "amount of time to delay this output, in measures"
      },
      "description" : "output incoming notes at specified delays",
      "type" : "note effects"
   },
   "noteexpression" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "expression*" : "expression to evaluate for this cable. example expression to route notes with pitch greater than 80 and velocity less than 60:\n\"p > 80 && v < 60\""
      },
      "description" : "control where notes are routed based upon evaluated expressions. the variable \"p\" represents pitch, and \"v\" represents velocity",
      "type" : "note effects"
   },
   "notefilter" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "C#-2 (1)" : "",
         "C-2 (0)" : "",
         "D#-2 (3)" : "",
         "D-2 (2)" : "",
         "E-2 (4)" : "",
         "F#-2 (6)" : "",
         "F-2 (5)" : "",
         "G-2 (7)" : ""
      },
      "description" : "only allow a certain pitches through",
      "type" : "note effects"
   },
   "noteflusher" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "flush" : "click to flush notes"
      },
      "description" : "send a note-off for all notes",
      "type" : "note effects"
   },
   "notegate" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "open" : "if notes are allowed to pass"
      },
      "description" : "allow or disallow notes to pass through",
      "type" : "note effects"
   },
   "notehocket" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "*" : "generate a new random seed",
         "<" : "go to previous seed",
         ">" : "go to next seed",
         "beat length" : "restart the deterministic random sequence at this interval",
         "seed" : "number that determines the random sequence",
         "weight *" : "chance that note goes to this destination"
      },
      "description" : "sends notes to random destinations",
      "type" : "note effects"
   },
   "notehumanizer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "time" : "amount of timing randomness, in milliseconds.",
         "velocity" : "amount of velocity randomness"
      },
      "description" : "add randomness to timing and velocity",
      "type" : "note effects"
   },
   "notelatch" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "use note on messages to toggle notes on and off",
      "type" : "note effects"
   },
   "notelooper" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "canvas" : "canvas of recorded notes",
         "clear" : "clear pattern",
         "del/mute" : "if \"write\" is enabled, erase notes as the playhead passes over them. otherwise, just mute them.",
         "load*" : "restore pattern",
         "num bars" : "set loop length in measures",
         "store*" : "save pattern",
         "write" : "should input should be recorded?"
      },
      "description" : "note loop recorder with overdubbing and replacement functionality",
      "type" : "instruments"
   },
   "noteoctaver" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "octave" : "number of octaves to raise or lower",
         "retrigger" : "immediately replay current notes when changing the transpose amount"
      },
      "description" : "transpose a note by octaves",
      "type" : "note effects"
   },
   "notepanalternator" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "one" : "pan position, .5 is centered",
         "two" : "pan position, .5 is centered"
      },
      "description" : "sets a note's pan, alternating between two values, for the internal synths that support panned notes",
      "type" : "note effects"
   },
   "notepanner" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "pan" : "pan position, .5 is centered"
      },
      "description" : "sets a note's pan, for the internal synths that support panned notes",
      "type" : "note effects"
   },
   "notepanrandom" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "center" : "center pan position",
         "spread" : "amount of randomness"
      },
      "description" : "sets a note's pan to random values, for the internal synths that support panned notes",
      "type" : "note effects"
   },
   "noterangefilter" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "max" : "maximum pitch allowed",
         "min" : "minimum pitch allowed",
         "wrap" : "instead of rejecting notes outside of this range, should we wrap them to the range instead?"
      },
      "description" : "only allows notes through within a certain pitch range",
      "type" : "note effects"
   },
   "noteratchet" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "duration" : "total length of time repeats should last",
         "skip first" : "don't replay input note. this allows you to more easily separate the initial note from the ratcheted notes.",
         "subdivision" : "length of each repeat"
      },
      "description" : "rapidly repeat an input note over a duration",
      "type" : "note effects"
   },
   "noterouter" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "route" : "the noterouter's destination module"
      },
      "description" : "allows you to control where notes are routed to using a UI control. to add destinations to the list, patch them as a target",
      "type" : "note effects"
   },
   "notesequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "<" : "shift the sequence to the left",
         ">" : "shift the sequence to the right",
         "clear" : "clear all steps",
         "grid" : "patch a grid in here from a \"midicontroller\" module",
         "interval" : "note length",
         "len" : "randomize the length of each step's note.",
         "len*" : "length for this column",
         "length" : "length that the sequence below should play. the overall grid length can be changed by adjusting \"gridsteps\" in the triangle menu.",
         "loop reset" : "when sequence loops, reset to here instead. send a \"downbeat\"-style message from a pulser to restart the sequence from the first step.",
         "notemode" : "which set of pitches should the rows represent?",
         "octave" : "octave of the bottom pitch of this sequence",
         "pitch" : "randomize pitches in the sequence. hold shift to constrain the randomization to only pick roots and fifths.",
         "rand len chance" : "when clicking the random length button, what is the chance that a step gets changed?",
         "rand len range" : "when clicking the random length button, how much will the length change?",
         "rand pitch chance" : "when clicking the random pitch button, what is the chance that a step gets changed?",
         "rand pitch variety" : "how many different random pitches should we generate?",
         "rand vel chance" : "when clicking the random velocity button, what is the chance that a step gets changed?",
         "rand vel density" : "when clicking the random velocity button, what are the chances that a step should have a note?",
         "random" : "randomize pitch, length, and velocity of all steps.",
         "tone*" : "pitch for this column",
         "vel" : "randomize the velocity of each step's note.",
         "vel*" : "velocity for this column",
         "x offset" : "x offset of attached grid controller",
         "y offset" : "y offset of attached grid controller"
      },
      "description" : "looping sequence of notes at an interval. pair with a \"pulser\" module for more interesting step control. hold \"shift\" to adjust step length.",
      "type" : "instruments"
   },
   "notesinger" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "oct" : "octave to adjust output pitch by"
      },
      "description" : "output a note based on a detected pitch",
      "type" : "instruments"
   },
   "notesorter" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "pitch *" : "pitch to use for this outlet"
      },
      "description" : "separate notes by pitch. any unmapped pitches go through the standard outlet.",
      "type" : "note effects"
   },
   "notestepper" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "length" : "length of the sequence",
         "reset" : "reset to the start"
      },
      "description" : "output notes through a round robin of patch cables, to create sequential variety",
      "type" : "note effects"
   },
   "notestream" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "reset" : "reset the pitch range"
      },
      "description" : "view a stream of notes as they're played",
      "type" : "note effects"
   },
   "notestrummer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "strum" : "move the slider past each note to strum it"
      },
      "description" : "send a chord into this, and move a slider to strum each note of the chord",
      "type" : "note effects"
   },
   "notetable" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "clear" : "clear grid",
         "grid" : "patch a grid in here from a \"midicontroller\" module",
         "length" : "the number of pitches",
         "notemode" : "which set of pitches should the rows represent?",
         "octave" : "octave of the bottom pitch of this sequence",
         "rand pitch chance" : "when clicking the random pitch button, what is the chance that a step gets changed?",
         "rand pitch range" : "when clicking the random pitch button, how far will the pitch change?",
         "random pitch" : "randomize pitches in the sequence. hold shift to constrain the randomization to only pick roots and fifths.",
         "tone*" : "pitch for this column",
         "x offset" : "x offset of attached grid controller",
         "y offset" : "y offset of attached grid controller"
      },
      "description" : "map a pitch (starting from zero) to a scale pitch",
      "type" : "note effects"
   },
   "notetofreq" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "takes an input note, and outputs that note's frequency in hertz",
      "type" : "modulators"
   },
   "notetoggle" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "turn a control on or off depending on if there are any input notes",
      "type" : "other"
   },
   "notetoms" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "takes an input note, and outputs the period of that note's frequency in milliseconds. useful for setting delay lines to create specific pitches.",
      "type" : "modulators"
   },
   "notetopulse" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "trigger a pulse whenever a note is received",
      "type" : "pulse"
   },
   "notewrap" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "min" : "bottom of pitch range",
         "range" : "number of semitones before wrapping back down to min pitch"
      },
      "description" : "wrap an input pitch to stay within a desired range",
      "type" : "note effects"
   },
   "oscillator" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "adsr len" : "view length of ADSR controls",
         "detune" : "when unison is 1, detunes oscillator by this amount. when unison is 2, one oscillator is tuned normally and the other is detuned by this amount. when unison is >2, oscillators are randomly detuned within this range.",
         "env" : "[none]",
         "envA" : "volume envelope attack",
         "envD" : "volume envelope decay",
         "envR" : "volume envelope release",
         "envS" : "volume envelope sustain",
         "envfilter" : "[none]",
         "envfilterA" : "filter envelope attack",
         "envfilterD" : "filter envelope decay",
         "envfilterR" : "filter envelope release",
         "envfilterS" : "filter envelope sustain",
         "fmax" : "frequency cutoff of lowpass filter at the max of the envelope. set this slider to the max to disable the filter",
         "fmin" : "frequency cutoff of lowpass filter at the min of the envelope",
         "lite cpu" : "only recalculate some parameters once per buffer, to reduce CPU load. can make pitch bends and rapid modulation sound worse in some scenarios.",
         "mult" : "multiply frequency of incoming pitch",
         "osc" : "oscillator type",
         "phase" : "phase offset of oscillator, and phase offset between unison voices. useful to patch into with a very fast modulator, to achieve phase modulation.",
         "pw" : "pulse width (or shape for non-square waves)",
         "q" : "resonance of lowpass filter",
         "shuffle" : "stretches and squeezes every other cycle of the waveform",
         "soften" : "soften edges of square and saw waveforms",
         "syncf" : "frequency to reset the phase, when \"syncmode\" is set to \"freq\"",
         "syncmode" : "turns on sync mode, to reset the phase at a specified frequency",
         "syncratio" : "ratio of oscillator frequency to reset the phase, when \"syncmode\" is set to \"ratio\"",
         "unison" : "how many oscillators to play for one note",
         "vel2env" : "how much should the input velocity affect the speed of the volume and filter envelopes?",
         "vel2vol" : "how much should the input velocity affect the output volume?",
         "vol" : "this oscillator's volume",
         "width" : "controls how voices are panned with unison is greater than 1"
      },
      "description" : "polyphonic enveloped oscillator. modulations (with MPE support): modwheel closes filter further (if filter is enabled), pressure decreases detune amount",
      "type" : "synths"
   },
   "oscoutput" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "label*" : "label to send slider value. the message will be sent in the format /bespoke/[label] [value]",
         "note out address" : "label to send input notes. the message will be sent in the format /bespoke/[label] [pitch] [velocity]",
         "osc out address" : "destination to send OSC messages to",
         "osc out port" : "port to send OSC messages to",
         "slider*" : "sends a value to the address. try patching a modulator into this, such as a leveltocv module to send audio levels."
      },
      "description" : "send OSC messages when slider values change or when notes are received",
      "type" : "other"
   },
   "output" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "ch" : "channel (or channels, if you want stereo) to send audio to"
      },
      "description" : "route audio in here to send it to an output channel (your speakers or audio interface)",
      "type" : "audio effects"
   },
   "panner" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "pan" : "amount to send signal to the left and right channels. a value of 0 is centered.",
         "widen" : "delay a channel by this many samples. results in a pan-like effect where the sound seems to come from from a direction."
      },
      "description" : "pan audio left and right. also, converts a mono input to a stereo output.",
      "type" : "audio effects"
   },
   "pitchbender" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "bend" : "bend amount, in semitones"
      },
      "description" : "add pitch bend to notes",
      "type" : "note effects"
   },
   "pitchchorus" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "passthrough" : "should the original audio pass through?"
      },
      "description" : "output pitch-shifted version of input audio, based on input midi notes. pitch 60 is the reference pitch used.",
      "type" : "unknown"
   },
   "pitchdive" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "start" : "semitone offset to start from",
         "time" : "time in milliseconds to ramp from pitch offset into input pitch"
      },
      "description" : "use pitchbend to settle into an input pitch from a starting offset",
      "type" : "note effects"
   },
   "pitchpanner" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "left" : "pitch that represents full left pan",
         "right" : "pitch that represents full right pan"
      },
      "description" : "add pan modulation to notes based upon input pitch, so low pitches are panned in one direction and high pitches are panned in another",
      "type" : "note effects"
   },
   "pitchremap" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "from*" : "pitch to change",
         "to*" : "desired pitch"
      },
      "description" : "remap input pitches to different output pitches",
      "type" : "note effects"
   },
   "pitchsetter" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "pitch" : "the pitch to use"
      },
      "description" : "set an incoming note to use a specified pitch",
      "type" : "note effects"
   },
   "pitchshift" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "ratio" : "amount to pitchshift by (a value of 1 indicates no shift)",
         "ratioselector" : "shortcuts to useful pitch ratios"
      },
      "description" : "shifts a signal's pitch",
      "type" : "effect chain"
   },
   "pitchtocv" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "max" : "output for pitch 127",
         "min" : "output for pitch 0"
      },
      "description" : "take a note's pitch and convert it to a modulation value",
      "type" : "modulators"
   },
   "pitchtospeed" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "ref freq" : "the output is the input frequency divided by this number"
      },
      "description" : "convert an input pitch to a speed ratio. you could use this to control a sample's playback speed and make it playable with a keyboard.",
      "type" : "modulators"
   },
   "pitchtovalue" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "output midi pitch value",
      "type" : "modulators"
   },
   "playsequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "grid" : "patch a grid in here from a \"midicontroller\" module",
         "interval" : "the step size",
         "link columns" : "if the mute/delete control should be shared across the entire column",
         "load*" : "load the sequence stored in this slot",
         "measures" : "the loop length",
         "mute/delete*" : "if write is disabled, mute this row. if write is enabled, clear the steps as the playhead passes them",
         "note repeat" : "if held notes should repeat every step",
         "store*" : "store the current sequence to this slot",
         "write" : "if the current input should be written to the sequence. this will also delete steps if mute/delete is enabled for this row"
      },
      "description" : "drum sequencer that allows you to punch in to record and overdub steps, inspired by the pulsar-23 drum machine",
      "type" : "instruments"
   },
   "plugin" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "open" : "show the plugin window",
         "panic" : "send \"all notes off\" and \"all sounds off\" to this plugin in order to silence it immediately",
         "preset" : "choose from saved plugin presets",
         "program change" : "send a program change message to the plugin instance",
         "save as" : "save the current plugin settings as a preset to load again later",
         "show parameter" : "select parameters to display them, so they can be adjusted from within bespoke's interface. if a plugin has more than 20 parameters, this list will initially be empty. in that case, to make a parameter appear in this list, wiggle it within the plugin's interface.",
         "vol" : "adjust the output volume"
      },
      "description" : "a hosted plugin instance, such as a VST",
      "type" : "unknown"
   },
   "polyrhythms" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "length*" : "number of steps for this line",
         "note*" : "pitch to use for this line"
      },
      "description" : "looping sequence with lines on different divisions",
      "type" : "instruments"
   },
   "portamento" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "glide" : "time to glide, in milliseconds",
         "mode" : "always: always glide to new notes\nretrigger held: bend to notes if the prior note is held, and retrigger\nbend held: bend to notes if the prior note is held, without retriggering"
      },
      "description" : "only allows one note to play at a time, and uses pitch bend to glide between notes",
      "type" : "note effects"
   },
   "prefab" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "disband" : "free all modules from this prefab",
         "load" : "load a .pfb",
         "save" : "save as a .pfb file"
      },
      "description" : "create a collection of modules that can be loaded from the \"prefabs\" menu. drag and drop modules onto here to add them to the prefab. drag the grey cable to any modules you want to remove from the prefab.",
      "type" : "other"
   },
   "pressure" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "pressure" : "pressure amount"
      },
      "description" : "add pressure modulation to notes",
      "type" : "note effects"
   },
   "pressuretocv" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "max" : "output for pressure 127",
         "min" : "output for pressure 0"
      },
      "description" : "take a note's pressure and convert it to a modulation value",
      "type" : "modulators"
   },
   "pressuretomodwheel" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "takes midi pressure modulation input and changes it to modwheel modulation",
      "type" : "note effects"
   },
   "pressuretovibrato" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "vibinterval" : "vibrato speed",
         "vibrato" : "amount of vibrato"
      },
      "description" : "takes midi pressure modulation input and changes it to vibrato, using pitch bend",
      "type" : "note effects"
   },
   "previousnote" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "when receiving a note on, output the prior note on that we received",
      "type" : "note effects"
   },
   "pulsebutton" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "pulse" : "trigger a pulse"
      },
      "description" : "trigger a pulse with a button press",
      "type" : "pulse"
   },
   "pulsechance" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "*" : "generate a new random seed",
         "<" : "go to previous seed",
         ">" : "go to next seed",
         "chance" : "chance that pulses are allowed through",
         "deterministic" : "allow for randomness to be repeated over an interval",
         "seed" : "number that determines the random sequence. send reset pulses to restart the deterministic random sequence."
      },
      "description" : "randomly allow pulses through, based on chance",
      "type" : "pulse"
   },
   "pulsedelayer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "delay" : "time to delay, in fractions of a measure"
      },
      "description" : "delay pulses",
      "type" : "pulse"
   },
   "pulsedisplayer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "description" : "see what flags are on pulses",
      "type" : "pulse"
   },
   "pulseflag" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "flag" : "property to add",
         "replace" : "if disabled, the above flag is appended to the pulse's flags. if enabled, the pulse's flags are replaced by the above flag."
      },
      "description" : "set properties on pulses",
      "type" : "pulse"
   },
   "pulsegate" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "allow" : "can pulses pass through?"
      },
      "description" : "control if pulses are allowed through",
      "type" : "pulse"
   },
   "pulsehocket" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "*" : "generate a new random seed",
         "<" : "go to previous seed",
         ">" : "go to next seed",
         "seed" : "number that determines the random sequence. send reset pulses to restart the deterministic random sequence.",
         "weight *" : "chance that pulse goes to this destination"
      },
      "description" : "sends pulses to randomized destinations",
      "type" : "pulse"
   },
   "pulselimit" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "limit" : "limit number of pulses to pass through",
         "reset" : "reset the counter of seen pulses"
      },
      "description" : "limit the number of pulses allowed to pass through",
      "type" : "pulse"
   },
   "pulser" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "div" : "measure division, when using \"div\" as the interval",
         "interval" : "rate to send pulses",
         "offset" : "pulse time offset, in fractions of the interval",
         "random" : "tell pulsed modules to randomize their position",
         "reset" : "length of sequence before sending reset pulse",
         "restart" : "restart timer on \"free\" counter",
         "t" : "pulse interval in milliseconds",
         "timemode" : "when to send downbeat pulses, or set to \"free\" for pulses not locked to the transport"
      },
      "description" : "send pulse messages at an interval",
      "type" : "pulse"
   },
   "pulserouter" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "route" : "the pulserouter's destination module"
      },
      "description" : "allows you to control where pulses are routed to using a UI control. to add destinations to the list, patch them as a target",
      "type" : "pulse"
   },
   "pulsesequence" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         " - " : "advance the sequence backwards",
         "+" : "advance the sequence forward",
         "<" : "shift sequence to the left",
         ">" : "shift sequence to the right",
         "interval" : "length of each step within the sequence",
         "length" : "length of the sequence",
         "pulse" : "when enabled will send out pulses as per sequence when advancing with the buttons"
      },
      "description" : "defines a looping sequence of pulses",
      "type" : "pulse"
   },
   "pulsetrain" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "interval" : "length of each step within the sequence",
         "length" : "length of the sequence"
      },
      "description" : "defines a list of pulses to execute, once pulsed",
      "type" : "pulse"
   },
   "pumper" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "amount" : "amount to lower volume",
         "attack" : "how sharply the volume drops",
         "curve" : "how the volume returns",
         "interval" : "the rate to pump",
         "length" : "length of pump"
      },
      "description" : "dip the volume of a signal rhythmically, to emulate a \"pumping sidechain\" effect",
      "type" : "effect chain"
   },
   "push2control" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "description" : "use an ableton push 2 to control bespoke's interface",
      "type" : "other"
   },
   "quantizer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "quantize" : "the quantization interval",
         "repeat" : "when holding a note, should we repeat it every interval?"
      },
      "description" : "delay inputs until the next quantization interval",
      "type" : "note effects"
   },
   "radiosequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "grid" : "patch a grid in here from a \"midicontroller\" module",
         "interval" : "rate to advance",
         "length" : "length of sequence"
      },
      "description" : "sequence to only enable one value at a time. patch it to the \"enabled\" checkbox on several modules to only enable one module at a time. works well in conjunction with \"groupcontrol\" module.",
      "type" : "other"
   },
   "ramper" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "length" : "length of time to blend over",
         "start" : "begin blending (or, send a pulse to this module for the same result)",
         "target" : "the value to arrive at when the ramp is over"
      },
      "description" : "blend a control to a specified value over a specified time",
      "type" : "modulators"
   },
   "randomnote" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "interval" : "the note length",
         "offset" : "the amount of time to offset playback within the interval",
         "pitch" : "the pitch to use",
         "probability" : "the chance that a note will play each interval",
         "skip" : "after a note plays, don't play a note the next n-1 times that it would have played",
         "velocity" : "the velocity to use"
      },
      "description" : "play a note at a given interval with a random chance",
      "type" : "instruments"
   },
   "rhythmsequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "action *" : "action for this step. on = play note, hold = sustain note, off = no note",
         "degree *" : "scale degree offset for this step",
         "interval" : "rate to play notes at",
         "len act" : "length of the action column",
         "len deg" : "length of the scale degree offset column",
         "len oct" : "length of the octave offset column",
         "len vel" : "length of the velocity column",
         "length" : "length of the sequence",
         "link lengths" : "should there be one global length, or a length for each column?",
         "octave *" : "octave offset for this step",
         "vel *" : "velocity for this step"
      },
      "description" : "repeats held input notes, to turn a sustained note into a rhythm",
      "type" : "note effects"
   },
   "ringmodulator" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "dry/wet" : "how much of the original audio to use vs modulated audio",
         "freq" : "frequency to use. can also be set by patching a note input into this module.",
         "glide" : "how long an input note should take to glide to the desired frequency",
         "volume" : "volume output"
      },
      "description" : "modulate a signal's amplitude at a frequency",
      "type" : "audio effects"
   },
   "samplebrowser" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         " < " : "previous page",
         " > " : "next page"
      },
      "description" : "browse your system for samples. drag samples from here to your desired targets (sampleplayer, drumplayer, seaofgrain, etc)",
      "type" : "other"
   },
   "samplecanvas" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "canvas" : "canvas of samples. drag and drop samples onto here. canvas controls:\n-hold shift and drag a sample to duplicate\n-hold alt to drag a sample without snapping\n-hold ctrl while dragging to snap to an interval\n-hold shift and scroll to zoom\n-hold alt and grab empty space to move slide the canvas view\n-hold ctrl and grab empty space to zoom the canvas view",
         "clear" : "delete all elements",
         "delete" : "delete highlighted elements",
         "drag mode" : "direction that elements can be dragged",
         "interval" : "grid subdivision interval",
         "measures" : "length of canvas in measures",
         "scrollh" : "horizontal scrollbar",
         "scrollv" : "vertical scrollbar",
         "timeline" : "control loop points",
         "view rows" : "number of visible rows"
      },
      "description" : "sample arranging view",
      "type" : "synths"
   },
   "samplecapturer" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "delete" : "clear this clip",
         "play" : "play this clip",
         "record" : "should we record?",
         "save" : "save this clip to a file"
      },
      "description" : "[work in progress]record audio to short clips. recording starts when audio passes a threshold.",
      "type" : "audio effects"
   },
   "sampleplayer" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "16" : "auto-slice 16 slices",
         "32" : "auto-slice 32 slices",
         "4" : "auto-slice 4 slices",
         "8" : "auto-slice 8 slices",
         "append to rec" : "when recording, append to the previous recording, rather than clearing the sample first",
         "attack" : "speed at which gate blends open",
         "click sets cue" : "when true, clicking on the waveform will set the start position of the current cue",
         "cue len" : "length in seconds of the current cue. a value of zero will play to the end of the sample.",
         "cue speed" : "playback speed of the current cue",
         "cue start" : "start point in seconds of the current cue",
         "cue stop" : "stop playing this cue if a note-off is received",
         "cuepoint" : "sets the current cue to edit",
         "grabhovered" : "grab a sample of this cue to drop onto another module",
         "load" : "show a file chooser to load a sample",
         "loop" : "wrap playhead to beginning when it reaches end",
         "pause" : "pause playing and leave playhead where it is",
         "play" : "start playing from the current playhead",
         "play cue" : "play the current cue",
         "playhovered" : "play this cue",
         "record" : "record audio input into our sample buffer. clears the current sample.",
         "record as clips" : "when recording, only record when there is enough input to open the gate, and mark up each recorded segment with cue points",
         "release" : "speed at which gate blends closed",
         "save" : "save this sample to a file",
         "searchresult*" : "click to download this youtube search result. downloading long videos may take a while.",
         "select played" : "when true, any cue point played via incoming notes will become the current cue",
         "show grid" : "show a quarter note grid (when zoomed in far enough)",
         "speed" : "current playback speed",
         "stop" : "stop playing and reset playhead",
         "threshold" : "volume threshold to open up the gate for recording",
         "trim" : "discard all audio outside the current zoom range",
         "volume" : "output gain",
         "youtube" : "download the audio of the youtube URL currently on your clipboard",
         "yt:" : "search youtube for this string"
      },
      "description" : "sample playback with triggerable cue points, clip extraction, and youtube search/download functionality. resize this module larger to access additional features. if you have a youtube URL in your clipboard, a button will appear to allow you to download the audio.",
      "type" : "synths"
   },
   "sampler" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "env" : "volume envelope",
         "envA" : "volume envelope attack",
         "envD" : "volume envelope decay",
         "envR" : "volume envelope release",
         "envS" : "volume envelope sustain",
         "passthrough" : "should input audio pass through as we're recording?",
         "pitch" : "should we attempt pitch-correct the audio?",
         "rec" : "enable to clear the current recording, and record new audio once the input threshold is reached",
         "thresh" : "when recording is enabled, exceed this threshold with input audio to begin recording",
         "vol" : "output volume"
      },
      "description" : "very basic polyphonic pitched sample player and recorder. send audio in, and use note input to play the recorded audio.",
      "type" : "synths"
   },
   "samplergrid" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "clear" : "when enabled, clears any pressed grid squares",
         "duplicate" : "what enabled, duplicates last pressed sample onto any pressed grid squares",
         "edit" : "enable controls to adjust recorded sample for last pressed grid square",
         "end" : "sample end",
         "grid" : "patch a grid in here from a \"midicontroller\" module",
         "passthrough" : "should the incoming audio pass through to the output?",
         "start" : "sample start",
         "vol" : "the output volume"
      },
      "description" : "record input onto pads, and play back the pads. intended to be used with an 64-pad grid controller.",
      "type" : "audio effects"
   },
   "savestateloader" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "load *" : "loads specified savestate file. shift-click to choose a new file."
      },
      "description" : "loads other savestate files (and unloads the current savestate). the number of buttons can be adjusted in the triangle menu.",
      "type" : "other"
   },
   "scale" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "PPO" : "pitches per octave",
         "degree" : "",
         "intonation" : "which method to use to tune the scale",
         "load KBM" : "load KBM file to determine keyboard mapping",
         "load SCL" : "load SCL file to determine scale",
         "note" : "the pitch that maps to the frequency defined in \"tuning\"",
         "root" : "root note of the scale",
         "scale" : "which set of notes to use",
         "tuning" : "what frequency does the pitch defined in \"note\" represent?"
      },
      "description" : "controls the global scale used by various modules",
      "type" : "other"
   },
   "scaledegree" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "degree" : "amount to transpose",
         "diatonic" : "should we keep transposed notes in the scale?",
         "retrigger" : "immediately replay current notes when changing the transpose amount"
      },
      "description" : "transpose input based on current scale",
      "type" : "note effects"
   },
   "scaledetect" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "matches" : "matching scales for this root",
         "reset" : "reset the input collection of notes"
      },
      "description" : "detect which scales fit a collection of entered notes. the last played pitch is used as the root.",
      "type" : "note effects"
   },
   "script" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "?" : "show scripting reference",
         "a" : "variable for the script to use, can be modulation by other sources. access via me.get(\"a\")",
         "b" : "variable for the script to use, can be modulation by other sources. access via me.get(\"b\")",
         "c" : "variable for the script to use, can be modulation by other sources. access via me.get(\"c\")",
         "code" : "write code here. press ctrl-R to execute the code, or ctrl-shift-R to just execute the current block.",
         "d" : "variable for the script to use, can be modulation by other sources. access via me.get(\"d\")",
         "load" : "load selected script",
         "loadscript" : "choose a script from here, then press \"load\"",
         "run" : "click here to execute the code, or press ctrl-R",
         "save as" : "save the current script",
         "stop" : "cancel any events scheduled by this script",
         "style" : "choose a text theme, from script_styles.json"
      },
      "description" : "python scripting for livecoding notes and module control",
      "type" : "other"
   },
   "scriptstatus" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "reset all" : "resets scope variables"
      },
      "description" : "shows everything in the current python scope, for debugging",
      "type" : "other"
   },
   "seaofgrain" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "display length" : "amount of sample to view",
         "gain *" : "volume of this voice",
         "keyboard base pitch" : "midi pitch that represents the start of the sample",
         "keyboard num pitches" : "amount of pitches to assign across the sample",
         "len ms *" : "length of each grain in milliseconds",
         "load" : "load a sample file",
         "octaves *" : "should we add octaves and fifths?",
         "offset" : "where to start view of the sample",
         "overlap *" : "number of overlapping grains",
         "pan *" : "stereo panorama of grain placement",
         "pos *" : "position of this voice within the sample",
         "pos r *" : "randomization of grain start point",
         "record" : "record input as the granular buffer, to use seaofgrain a live granular delay",
         "spacing r*" : "randomization of time between grains",
         "speed *" : "speed of grain playback",
         "speed r *" : "randomization of grain speed",
         "volume" : "output volume",
         "width *" : "stereo width of grain placement"
      },
      "description" : "granular synth, playable with sliders or MPE input",
      "type" : "synths"
   },
   "selector" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "selector" : "which value should be set to 1"
      },
      "description" : "radio button control to only enable one value at a time. patch it to the \"enabled\" checkbox on several modules to only enable one module at a time. works well in conjunction with \"groupcontrol\" module.",
      "type" : "other"
   },
   "send" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "amount" : "amount to send out the right-side cable",
         "crossfade" : "when true, output of the left-side cable is reduced as \"amount\" increases"
      },
      "description" : "duplicate a signal and send it to a second destination",
      "type" : "audio effects"
   },
   "signalclamp" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "max" : "maximum output value",
         "min" : "minimum output value"
      },
      "description" : "clamps an audio signal's value within a range",
      "type" : "audio effects"
   },
   "signalgenerator" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "detune" : "amount to detune from specified frequency",
         "freq" : "signal frequency",
         "freq mode" : "what mode should we use for input notes? \"instant\" changes to the input note's frequency instantly, \"ramp\" ramps to the frequency over time, and \"slider\" allows you to use a slider to interpolate between the last two input notes",
         "mult" : "multiplier for frequency",
         "osc" : "oscillator type",
         "phase" : "phase offset",
         "pw" : "pulse width (or shape for non-square waves)",
         "ramp" : "amount of time to ramp to input frequency",
         "shuffle" : "stretches and squeezes every other cycle of the waveform",
         "slider" : "slider to interpolate between last two input pitches",
         "soften" : "soften edges of square and saw waveforms",
         "syncf" : "frequency to reset the phase, when \"syncmode\" is set to \"freq\"",
         "syncmode" : "turns on sync mode, to reset the phase at a specified frequency",
         "syncratio" : "ratio of oscillator frequency to reset the phase, when \"syncmode\" is set to \"ratio\"",
         "vol" : "output volume"
      },
      "description" : "basic oscillator signal. send a note into it to set the frequency, and send a pulse to reset the phase.",
      "type" : "synths"
   },
   "slidersequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "division" : "rate to progress",
         "note*" : "pitch for this element",
         "playing*" : "is this element playing?",
         "time*" : "time to trigger this element",
         "vel*" : "velocity of this element"
      },
      "description" : "trigger notes along a continuous timeline",
      "type" : "instruments"
   },
   "smoother" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "input" : "set a value to smooth, patch a modulator into here",
         "smooth" : "amount of smoothing to apply"
      },
      "description" : "outputs a smoothed value of the input",
      "type" : "modulators"
   },
   "snapshots" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "add" : "snapshot the currently connected controls to the next available snapshot slot",
         "blend" : "length of time in milliseconds over which to blend snapshot values",
         "delete" : "when clicking/selecting a snapshot, delete that slot (alternately: hold the alt/option key)",
         "random" : "randomize connected controls",
         "snapshot" : "jump to a snapshot",
         "snapshot label" : "assign a label to this snapshot",
         "store" : "when clicking/selecting a snapshot, store into that slot (alternately: hold the shift key)"
      },
      "description" : "save and restore sets of values. connect the grey circle to modules to affect all controls on that module. connect the purple circle to a control to affect only that control. shift-click on the grid to store a snapshot to that square, and click on a grid square to load that snapshot. alt/option-click to delete a snapshot, and ctrl/command-click to rename a snapshot.",
      "type" : "other"
   },
   "songbuilder" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : true,
      "controls" : 
      {
         "activate first scene on stop" : "when stopping, activate the first scene. it is recommended that you use the first scene as an \"off\" scene, and have it disable all song elements.",
         "add target" : "add a targeted control for scenes to affect",
         "bars*" : "length in bars that this scene should play for",
         "change quantize" : "when a change should happen after pressing the play button on a scene. \"switch\" changes immediately, and \"jump\" changes immediately and also resets the global transport.",
         "checkbox*" : "value to use for target in this scene",
         "color*" : "color to theme this target",
         "context*" : "options for this scene",
         "contextmenu*" : "options for this step",
         "dropdown*" : "value to use for target in this scene",
         "go*" : "play this scene",
         "loop" : "enable a loop within the sequence",
         "loop end" : "loop step index that the loop ends",
         "loop start" : "loop step index to start the loop on",
         "move left" : "move this target left in the scene",
         "move right" : "move this target right in the scene",
         "name*" : "name of this scene",
         "pause" : "hold the sequence on the current scene",
         "play" : "play the sequence",
         "play from*" : "play sequence from this step",
         "scene*" : "name of scene for this step",
         "stop" : "stop the sequence",
         "type" : "change the control display type for this target",
         "use sequencer" : "show scene sequencer",
         "value*" : "value to use for target in this scene"
      },
      "description" : "large-scale organizer to arrange settings into scenes and then sequence them. this is bespoke's \"song mode\"",
      "type" : "other"
   },
   "spectrum" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "description" : "display audio signal's spectral data",
      "type" : "audio effects"
   },
   "splitter" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "description" : "splits a stereo signal into two mono signals, or duplicates a mono signal",
      "type" : "audio effects"
   },
   "stutter" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "16th" : "16th note stutter",
         "32nd" : "32nd note stutter",
         "64th" : "64th note stutter",
         "8th" : "8th note stutter",
         "dotted eighth" : "stutter on a dotted eighth interval",
         "double speed" : "stutter at double speed, high pitched",
         "free" : "stutter with the settings specified by the following sliders",
         "free length" : "length in seconds for \"free\" stutter mode",
         "free speed" : "rate for \"free\" stutter mode",
         "grid" : "patch a grid in here from a \"midicontroller\" module",
         "half note" : "half note stutter",
         "half speed" : "stutter at half speed, low pitched",
         "quarter" : "quarter note stutter",
         "ramp in" : "stutter with speed climbing up from zero to one",
         "ramp out" : "stutter with speed quickly falling to zero",
         "reverse" : "reversed half note stutter",
         "triplets" : "stutter on a triplet interval",
         "tumble down" : "decelerating stutter",
         "tumble up" : "accelerating stutter"
      },
      "description" : "captures and stutters input",
      "type" : "audio effects"
   },
   "subtract" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "value 1" : "",
         "value 2" : ""
      },
      "description" : "outputs the result of value 2 subtracted from value 1. value 1 and value 2 are intended to be patch targets for modulators.",
      "type" : "modulators"
   },
   "sustainpedal" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "sustain" : "should we hold the input notes?"
      },
      "description" : "keeps input notes sustaining",
      "type" : "note effects"
   },
   "takerecorder" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "start" : "[todo]"
      },
      "description" : "[abandoned module, possibly broken]",
      "type" : "unknown"
   },
   "timelinecontrol" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "dock" : "should we dock this module to the UI layer?",
         "length" : "length of timeline display, in measures",
         "loop" : "should we have a looping section?",
         "loop end" : "measure end of loop",
         "loop start" : "measure start of loop",
         "measure" : "current position. click to jump around.",
         "reset" : "reset to beginning"
      },
      "description" : "control global transport position",
      "type" : "other"
   },
   "timerdisplay" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "reset" : "reset timer to zero"
      },
      "description" : "displays a timer to indicate how long a patch has been running",
      "type" : "other"
   },
   "titlebar" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         " ? " : "show help",
         "autosave" : "every time a new module is added, trigger a save to data/savestate/autosave/, to help reload state in the event of a crash. can be quite slow if using modules with large samples.",
         "home" : "Moves the viewport to the \"home\" position, useful if you lost where you are in your savestate",
         "load" : "load a saved .bsk file to restore state",
         "load layout" : "[none]",
         "lookahead (exp.)" : "use lookahead scheduling, which is necessary for scriptmodule. gets automatically turned on when you use scriptmodule. so far, lookahead scheduling seems to not create any issues, but leaving this checkbox here just in case.",
         "new patch" : "reset to the layout specified in \"layout\" in userprefs.json",
         "play/pause" : "stop all audio processing (shift-p)",
         "save" : "save current state as .bsk file, to be restored later",
         "save as" : "save current state as a new .bsk file",
         "save layout" : "[none]",
         "settings" : "adjust preferences, saved as userprefs.json",
         "write audio" : "write the last 30 minutes of audio to your specified recordings_path"
      },
      "description" : "",
      "type" : "unknown"
   },
   "transport" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         " + " : "increase tempo by one",
         " - " : "decrease tempo by one",
         " < " : "nudge current time backward",
         " > " : "nudge current time forward",
         "play/pause" : "stop all audio processing (shift-p)",
         "reset" : "reset timeline to zero",
         "set tempo" : "",
         "swing" : "where the halfway point of musical time within the swing interval should fall. a value of .5 represents no swing.",
         "swing interval" : "interval over which to apply swing",
         "tempo" : "global tempo, in beats per minute",
         "timesigbottom" : "time signature bottom value",
         "timesigtop" : "time signature top value"
      },
      "description" : "controls tempo and current time position",
      "type" : "other"
   },
   "transposefrom" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "retrigger" : "immediately replay current notes when changing the transpose root or the scale",
         "root" : "root to transpose from"
      },
      "description" : "transpose input from a specified root to the root of the current scale. the primary usage of this would be to allow you to play a keyboard in C, but it gets transposed to the current scale.",
      "type" : "note effects"
   },
   "tremolo" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "amount" : "amount to lower volume",
         "duty" : "pulse width of LFO",
         "interval" : "speed of LFO",
         "offset" : "offsets LFO phase",
         "osc" : "LFO oscillator type"
      },
      "description" : "modulate signal's volume rhythmically",
      "type" : "effect chain"
   },
   "unstablemodwheel" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "amount" : "amount of mutation",
         "noise" : "fast-later mutation rate",
         "warble" : "slow-layer mutation rate"
      },
      "description" : "mutate MPE slide with perlin noise",
      "type" : "note effects"
   },
   "unstablepitch" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "amount" : "amount of mutation",
         "noise" : "fast-later mutation rate",
         "warble" : "slow-layer mutation rate"
      },
      "description" : "mutate MPE pitchbend with perlin noise",
      "type" : "note effects"
   },
   "unstablepressure" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "amount" : "amount of mutation",
         "noise" : "fast-later mutation rate",
         "warble" : "slow-layer mutation rate"
      },
      "description" : "mutate MPE pressure with perlin noise",
      "type" : "note effects"
   },
   "userprefseditor" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "audio_input_device" : "which device to use for audio input (requires restart)",
         "audio_output_device" : "which device to use for audio output (requires restart)",
         "autosave" : "should autosave be enabled on startup",
         "background_b" : "blue RGB value of canvas background",
         "background_g" : "green RGB value of canvas background",
         "background_r" : "red RGB value of canvas background",
         "buffersize" : "what buffer size to use with your audio device. lower values use require more CPU power, higher values add more latency. (requires restart)",
         "cable_alpha" : "opacity of the cables",
         "cable_drop_behavior" : "what should be behavior be when you drag a cable and drop it into empty space?",
         "cable_quality" : "visual resolution of the cables",
         "devicetype" : "what kind of audio device bespoke should use (requires restart)",
         "draw_background_lissajous" : "should the background lissajous curve draw",
         "draw_module_highlights" : "should modules visually flash in response to activity",
         "fade_cable_middle" : "should longer cables draw with a fadeout effect in the middle",
         "ffmpeg_path" : "the path to your ffmpeg installation (used for youtube downloading in sampleplayer module)",
         "grid_snap_size" : "grid size to use when snapping module position (hold command on mac or control everywhere else while dragging a module)",
         "height" : "height of bespoke's window on startup",
         "immediate_paste" : "when enabled, pasting values on UI controls will apply immediately instead of requiring you to press enter",
         "layout" : "what template bespoke should use on startup",
         "lissajous_b" : "blue RGB value of lissajous curve",
         "lissajous_g" : "green RGB value of lissajous curve",
         "lissajous_r" : "red RGB value of lissajous curve",
         "max_input_channels" : "number of input channels to allocate (requires restart)",
         "max_output_channels" : "number of output channels to allocate (requires restart)",
         "motion_trails" : "amount of visual motion blur to use (increases/decreases \"ghosting\" of previous frames)",
         "mouse_offset_x" : "x offset between system mouse position and bespoke's cursor placement",
         "mouse_offset_y" : "y offset between system mouse position and bespoke's cursor placement",
         "oversampling" : "global oversampling multiplier. uses additional CPU for higher-resolution audio processing. (requires restart)",
         "plugin_preference_order" : "semicolon-separated list of plugin formats, in preferred order. if a plugin exists with multiple formats, only the most preferred format will be shown. leave this blank to always show all plugins. (default value: \"VST3;VST;AudioUnit;LV2\")",
         "position_x" : "desired x position of upper-left corner",
         "position_y" : "desired y position of upper-left corner",
         "qwerty_to_pitch_mode" : "some modules can hear computer keyboard keys and automatically translate them to MIDI notes. This setting defines how your keyboard is interpreted based on other DAWs with a similar feature. \nAbleton:\noctave#1: A->L\ndown octave: Z\nup octave: X\n\nFruity:\noctave#1: Z->M\noctave#2: Q->I\ndown octave: ,\nup octave: .",
         "record_buffer_length_minutes" : "length of always-on recording buffer for \"write audio\" button in the title bar (requires restart)",
         "recordings_path" : "where \"write audio\" and multitrackrecorder wav files save",
         "samplerate" : "what sample rate to use with your audio device (requires restart)",
         "scroll_multiplier_horizontal" : "adjustment to horizontal mouse/trackpad scroll speed",
         "scroll_multiplier_vertical" : "adjustment to vertical mouse/trackpad scroll speed",
         "set_manual_window_position" : "should we force bespoke to a specific position on startup",
         "show_minimap" : "should the minimap be displayed (requires restart)",
         "show_tooltips_on_load" : "should tooltips be enabled on startup",
         "tooltips" : "what path we should use for the tooltip file (changing this allows for other languages to be used for tooltips)",
         "ui_scale" : "scale of UI layer (title bar, quickspawn menu, etc)",
         "vst_always_on_top" : "should plugin windows always stay on top of bespoke when opened",
         "width" : "width of bespoke's window on startup",
         "wrap_mouse_on_pan" : "when panning canvas, wrap mouse position around when it goes offscreen, to allow you to pan endlessly",
         "youtube_dl_path" : "the path to your youtube-dl installation (used for youtube downloading in sampleplayer module)",
         "zoom" : "desired canvas zoom level on startup"
      },
      "description" : "settings for bespoke. some settings changes require bespoke to be restarted before taking effect.",
      "type" : "unknown"
   },
   "valuesetter" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : true,
      "controls" : 
      {
         "set" : "click here to send the value (or, send a pulse to this module for the same result)",
         "slider" : "value to set",
         "value" : "value to set"
      },
      "description" : "set a specified value on a targeted control",
      "type" : "modulators"
   },
   "valuestream" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "speed" : "how quickly display should scroll"
      },
      "description" : "displays a control's value over time. connect the cable to a UI control to see how it is changing.",
      "type" : "other"
   },
   "velocitycurve" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "adjust velocity based upon a curve mapping",
      "type" : "note effects"
   },
   "velocityscaler" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "scale" : "amount to multiply velocity by"
      },
      "description" : "scale a note's velocity to be higher or lower",
      "type" : "note effects"
   },
   "velocitysetter" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "rand" : "randomness to reduce output velocity by",
         "vel" : "velocity to use"
      },
      "description" : "set a note's velocity to this value",
      "type" : "note effects"
   },
   "velocitystepsequencer" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "downbeat" : "should we reset the sequence every downbeat?",
         "interval" : "speed to advance sequence",
         "len" : "length of sequence",
         "vel*" : "velocity for this step"
      },
      "description" : "adjusts the velocity of incoming notes based upon a sequence",
      "type" : "note effects"
   },
   "velocitytochance" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "*" : "generate a new random seed",
         "<" : "go to previous seed",
         ">" : "go to next seed",
         "beat length" : "restart the deterministic random sequence at this interval",
         "full velocity" : "set velocity to full for notes that pass through",
         "seed" : "number that determines the random sequence"
      },
      "description" : "use a note's velocity to determine the chance that the note plays",
      "type" : "note effects"
   },
   "velocitytocv" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "0 at note off" : "output zero when note is released",
         "max" : "output for velocity 127",
         "min" : "output for velocity 0"
      },
      "description" : "take a note's velocity and convert it to a modulation value",
      "type" : "modulators"
   },
   "vibrato" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "vibinterval" : "speed of pitch bend oscillation",
         "vibrato" : "amount of pitch bend to add"
      },
      "description" : "add rhythmic oscillating pitch bend to notes",
      "type" : "note effects"
   },
   "vinylcontrol" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "control" : "enable/disable transport control. when you enable it, it will use the current speed as the reference speed (so, the output will output a value of 1 until you change the vinyl's speed)"
      },
      "description" : "modulator which outputs a speed value based upon control vinyl input audio. provide it with a stereo signal from control vinyl (like you'd use to control serato) patched in from an \"input\" module.",
      "type" : "modulators"
   },
   "vocoder" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "bands" : "how many frequency bands to use",
         "carrier" : "carrier signal gain",
         "f base" : "frequency for lowest band",
         "f range" : "frequency range to highest band",
         "input" : "input signal gain",
         "max band" : "volume limit for each frequency band",
         "mix" : "how much original input vs vocoded signal to output",
         "q" : "resonance of the bands",
         "ring" : "how long it should take the bands to \"cool down\"",
         "spacing" : "how frequency bands should be spaced",
         "volume" : "output gain"
      },
      "description" : "frequency band-based vocoder. this must be paired with a \"vocodercarrier\" module. voice should be routed into this module, and a synth should be patched into the vocodercarrier.",
      "type" : "audio effects"
   },
   "vocodercarrier" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "description" : "connect to \"vocoder\" or \"fftvocoder\" modules. send the synth audio into this module, and the voice audio into the vocoder module.",
      "type" : "audio effects"
   },
   "voicesetter" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "voice index" : "current set voice channel index"
      },
      "description" : "set a specific Voice channel index for a note",
      "type" : "note effects"
   },
   "volcabeatscontrol" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "agogo speed" : "",
         "clap speed" : "",
         "clave speed" : "",
         "closed hat decay" : "",
         "crash speed" : "",
         "hat grain" : "",
         "level *" : "",
         "open hat decay" : "",
         "stutter depth" : "",
         "stutter time" : "",
         "tom decay" : ""
      },
      "description" : "outputs MIDI data to control various aspects of the KORG volca beats drum machine",
      "type" : "note effects"
   },
   "waveformviewer" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "controls" : 
      {
         "draw gain" : "adjust waveform display scale",
         "freq" : "frequency to sync display to. gets automatically set if you patch a note input into this module",
         "length" : "number of samples to capture"
      },
      "description" : "waveform display",
      "type" : "audio effects"
   },
   "waveshaper" : 
   {
      "canReceiveAudio" : true,
      "canReceiveNote" : false,
      "canReceivePulses" : false,
      "controls" : 
      {
         "a" : "variable to use in expressions",
         "b" : "variable to use in expressions",
         "c" : "variable to use in expressions",
         "d" : "variable to use in expressions",
         "e" : "variable to use in expressions",
         "rescale" : "rescales input before feeding it into expression",
         "y=" : "waveshaping expression. try something like \"x+sin(x*pi*a)\". available variables: a,b,c,d,e = the sliders below. t = time. x1,x2,y1,y2 = biquad state storage."
      },
      "description" : "waveshaping with expressions",
      "type" : "audio effects"
   },
   "whitekeys" : 
   {
      "canReceiveAudio" : false,
      "canReceiveNote" : true,
      "canReceivePulses" : false,
      "description" : "remap the white keys that correspond to the C major scale to instead play the current global scale",
      "type" : "note effects"
   }
}