Docs CHOPs & sensing

TopToMidi

Samples an image at points you define and turns the pixel values into MIDI notes in a musical scale, with trigger gating, retrigger control, a MIDI-learned custom scale and output to a MIDI Out or VST CHOP.

∿ CHOPs & sensing ◆ Patreon:Base

This tool unlocks with Patreon. It installs through the same picker as everything else and unlocks with the Patreon Base tier or higher, connected from inside TouchDesigner. Everything else in the toolkit stays free and MIT, and the membership is what keeps that work moving.

Join on Patreon → How unlocking works →

What it is

TopToMidi plays your visuals. A sampler (a SOP's points, or a TOP's pixels) says where the input image is read; each sample point becomes a note. In Index mode a point triggers its own note whenever its pixel passes the threshold, so a pattern sweeping across the picture plays an arpeggio. In Value mode the pixel's brightness picks the note, quantised to Steps. The notes are mapped into a scale from a root note and octave, with custom scales you type in, or a scale learned live from a MIDI keyboard so you can duet with the picture. Trigger gating keeps busy scenes from spraying notes.

The notes go out to a MIDI Out CHOP, an Audio VST CHOP, or both, and ride out as a CHOP for anything else.

It is a member of the FNS operator family: pick it from the FNS tab of the OP Create dialog and it lands as one node.

Setup

Every scale except MIDI Scale is computed with the Python package mingus, which TouchDesigner does not bundle. The tool ships its own pip requirements file (the requirements DAT inside it) and installs it through TouchDesigner's Python Environment Manager. The Setup page's Status says whether mingus is available. When it is missing:

  • With a Python vEnv or Conda environment linked through the Python Environment Manager, press Install mingus. The tool writes TopToMidi.requirements.txt beside your .toe and hands it to the environment manager, which installs it into the linked environment in the background; Status reports the result. When the project has an environment context file, the requirements file is also registered in it, so a machine that opens the project with Auto Setup On Startup installs it on its own.
  • With no environment, create one in the Python Environment Manager (palette: tdPyEnvManager), then press Install mingus.

Nothing blocks TouchDesigner while this happens, and the tool never installs anything without the pulse.

Inputs and outputs

  • in2 (TOP): the image to sample.
  • out_viz (TOP): the sampling points drawn over the input.
  • out_sampled (TOP) and out_sampled_CHOP (CHOP): the sampled values.
  • out_notes (CHOP): the generated notes.

Processing while idle

Note processing runs only while a MIDI Out or VST CHOP is configured or the outputs are wired. MIDI learning runs only while a MIDI In CHOP is set. Steps follows the number of sample points while note processing runs.

Parameters

Input

ControlType / defaultWhat it does
SamplerSampler operatorempty TOP or SOP operator to define the pixel positions for sampling. These can be animated too, of course!
Offset 0.5Origo on / offoff By default many SOPs are centered around the origin. This quick toggle shifts the Sampler’s center to (0.5, 0.5).
Sample PreviewOpen2 button Opens a UI window to visualize and manually adjust the sampling points. Move them around with Left-Click+Dragging ; Scale with Scroll-Wheel (or +-), Reset with Middle-Click. It also has some options on the bottom left to always show the points, toggle Offset 0.5 and Reset the adjustments
Sample ChannelRgb menuLuminance Which attribute of the input image to perform further processing on.
Options: Luminance, Red, Green, Blue, Alpha, RGB Average, RGBA Average, RGB Maximum and 1 more
ThresholdThresh number0 Pre-processes the input image by thresholding between two values. This will also have an effect on when a note is triggered in Index Mapping Mode.
Re-RangeRerange on / offoff Re-ranges the thresholded image to 0-1. This parameter is only interesting in Value Mapping Mode.
Mapping ModeMode menu0 This is the most important parameter to determine the mapping of pixel values to MIDI notes, before assigning to a Scale. Index: The point/pixel indices of the Sampler determine the pitch of the notes, upon triggered by the sampled value reaching the Threshold. Notes are sustained while in the range. It is important to set a good Threshold with Index mode. Important to note that the number of Steps is determined by the number of points. Be careful not to use big textures or SOPs with many points (anyway MIDI is limited to 128 notes). Value: The sampled values determine the pitch of the notes, where the quantization is determined by the Steps parameter. It means if you have identical sampled values they will trigged the same note twice. Re-Range of the Threshold is suggested to be kept on usually. In this mode you are more free to set more sampling points!
Options: Index, Value
Trigger Options
Re-Trigger Gate LengthRetriggergatelen number0.2 Overall gate window in seconds. At 0 every trigger passes straight through. Above 0 the sampled pattern is held for this long after a trigger, so a new trigger (or a release) can happen at most once per window; changes that arrive inside the window are applied when it closes.
Trigger Gate LengthTriggergatelength number0.2 Seconds a sample point has to stay above the threshold before its note turns on. 0 = immediately.
Min Sustain LengthMinsustain number0 Minimum seconds a note stays on once triggered, even if the sample point drops below the threshold sooner.
Re-Trigger DelayRetrigger number0 Minimum seconds between two triggers of the same note. A new trigger inside this time is ignored.

Scale

ControlType / defaultWhat it does
ScaleScale menuMajor Determines the Scale Mode the triggered notes are mapped to. Scales determine a number of notes in a Scale, starting from a root note (Key). You can also define Custom Scales which will also show up in the dropdown! MIDI Scale is a special one, see later.
Options: Major, NaturalMinor, Chromatic, WholeTone, HarmonicMajor, HarmonicMinor, MelodicMinor, Bachian and 11 more
KeyRootnote menu, editableempty Sets the musical root note of the Scale. Can type any musical note notation, even wild things like A#bbb## (thanks to the mingus library). But usually the drop-down list should be more reasonable :)
Options: C, C#, D, D#, E, F, F#, G and 4 more
OctaveOctave number4 The octave of the root note.
StepsSteps number1 Number of MIDI notes to generate. In Index mode it is fixed to the number of sampling points. In Value mode it is the "quantization" of the pitch determined by the sampled pixel values.
Extend ModeExtendmode on / offoff When having more steps than the number of notes in the Scale, having this on will extend subsequent steps to the next octaves. Otherwise the same scale notes in the starting octave are repeated.
Edit Custom ScalesOpen button Opens a Table DAT where in each column you can define a custom scale name where each note can be defined in the rows below using standard musical notation. For example: C#3.
Keytrack LookupVelocitylookup operatorempty A multi-sample CHOP reference which can define the MIDI velocity based on the pitch.
MIDI Scale
MIDI In CHOPMidiref operatorempty Optional MIDI In CHOP (a MIDI keyboard) for MIDI Scale learn and live mode. Empty by default; name a sibling MIDI In CHOP, e.g. midiin1.
MIDI Scale LearnMidilearn on / offoff Can define a Custom Scale by hitting notes one-by-one on your MIDI In instrument.
MIDI LiveMidilive on / offoff Follows the keys currently held on the MIDI In CHOP as the scale, in real time (MIDI Scale only), instead of the learned one.
Live Octave OffsetLiveoctaveoffset number0 Octaves added to the notes taken live from the MIDI In CHOP while MIDI Live is on, so the tool can play along above (or below) the keys you hold.
Sync StepsSyncsteps on / offoff Syncs the number of steps to the number of incoming notes. This is not available when Extend Mode is on.
RandomizeRandomize on / offoff Randomize the order of notes.
SeedSeed number0 Seed of the randomization.

Output

ControlType / defaultWhat it does
MIDI ActiveActive on / offon Activates MIDI Out CHOP.
MIDI Out CHOPMidioutchop operatorempty MIDI Out CHOP to send notes to, referenced directly (no Null after it). Empty by default: drop a MIDI Out CHOP beside this tool and name it here, e.g. midiout1 for a sibling.
ChannelCh number0 MIDI channel to output notes on.
VST ActiveVstactive on / offoff Activates VST CHOP.
VST CHOPVstchop operatorempty Optional Audio VST CHOP to play notes on, referenced directly (no Null after it). Empty by default; name a sibling Audio VST CHOP, e.g. audiovst1.
ChannelVstchannel number1 VST channel to output notes on.

Setup

ControlType / defaultWhat it does
StatusStatusread-only textempty Read-only. Whether the Python package mingus (needed for every scale except MIDI Scale) is available, and what to do if it is not.
Install mingusInstall button Installs mingus into the Python environment linked by TouchDesigner's Python Environment Manager, in the background. Needs a linked Python vEnv; the Status line says when one is missing.
Re-checkRecheck button Looks for mingus again, e.g. after installing it by hand from the Python Environment Manager CLI.
Python Env Manager HelpEnvhelp button Opens the documentation of TouchDesigner's Python Environment Manager (tdPyEnvManager).

About

ControlType / defaultWhat it does
HelpTestopenhelp button Opens documentation.

Edit this page on GitHub →