Reference
Getting around
MIDoRI starts on the Home screen. Each tile opens a screen, and the small text on a tile shows its state (the BPM, the number of patches, whether Tombola is running…).
| Nav bar | What it does |
|---|---|
| Home (left) | Back to the Home screen. |
| Middle | The screen's own button: TAP on Tempo, Send on Knobs, Start / Stop on Tombola, Scan on Bluetooth. Otherwise it shows the screen name. |
| Back (right) | The screen you were on before (Home doesn't count). Pressing it again flips between the two, so you can go XYPad ⇄ Knobs with one tap. |
The Pads, Knobs and XYPad screens are empty until a script or plugin fills them. The SD card files come with
plugins that do (in /sd/plugins/, loaded at start-up), and the
examples show how to write your own.
Screens a plugin builds from several parts (a layout) get their own tile on Home.
Pads
A grid of buttons for one-shot actions: a drum hit, a scene change, starting a phrase. Each pad has a label and a color and plays whatever its script tells it to. Several fingers at once are fine.
Pad types
| Type | Behavior |
|---|---|
| trigger | Fires once when you press it (the default). |
| momentary | On while your finger is down, off when you lift it: good for holding a note or an effect. |
| toggle | Each press flips it on or off, and it stays lit while on: good for Hold, mute or Play. |
From a script
dev = MIDI::Device.new(MIDIDevices.sam2695)
UI.pad(1, label: "Kick", color: :red) { dev.trigger(36, 127, channel: 9) }
UI.pad(2, label: "Hold", color: :yellow, type: :momentary) { |down| ... }
UI.pad(3, label: "Play", color: :green, type: :toggle) { |on| on ? UI::Tempo.start : UI::Tempo.stop }
UI.pad_label(1, "Kick!") # also pad_color, pad_state, pad_clear
UI.show(:pads)Colors: :red :green :blue :yellow :cyan :magenta :orange :purple :white :gray. The blocks run while the
script keeps calling UI.process.
Knobs
Knobs for values you set and leave: cutoff, resonance, volume, effect sends. Each bank (A–D) is a full set of knobs with its own labels and colors, for example A for the synth, B for drums and C for effects.
| Touch | What it does |
|---|---|
| Drag around a knob | Turns it like a real knob: the tip of the gauge stays under your finger. You can grab anywhere in the knob's cell, and the farther from the center you hold, the finer the control. |
| Several fingers | Turn several knobs at once. |
| A / B / C / D (right strip) | Switch banks. Switching doesn't send anything; the other banks keep their values. |
| Send (nav bar) | Sends the current values of the visible bank again, for gear you plugged in afterwards. |
A knob sends only when its value changes. Defining a knob doesn't send its starting value; press Send (or call
UI.knob_send_all) to line your gear up with the screen.
From a script
UI.knob(1, label: "Cutoff", color: :cyan, value: 64) { |v| dev.control_change(74, v.to_i) }
UI.knob(2, bank: 2, label: "Pan", origin: :center, value: 64) { |v| dev.control_change(10, v.to_i) }
UI.knob(3, label: "BPM", min: 40, max: 240) { |v| UI::Tempo.bpm = v }
UI.knob_send_all(bank: :all)
UI.knobsOpen in the simulator ▶Options: min: / max: (0–127), step: (1; 0 for continuous), origin: :center
for a gauge that grows both ways, sensitivity: (1.0).
Details: docs/KNOBS.md (Japanese)
XYPad
A surface you play with your fingers: across picks the pitch, up and down moves a CC. Each finger plays on its own MIDI channel, so every note can bend and open its filter on its own.
| Touch | What it does |
|---|---|
| Put a finger down | The screen is split into columns, one per note of the scale. Where your finger lands picks the note. |
| Slide sideways | Bends the pitch from where you landed: sliding across the whole width bends by the glide range (2 semitones by default). |
| Slide up / down | Sends a CC (74 by default, often the filter cutoff). Top is the highest value. |
| Lift | Note off. With Hold on, the note keeps sounding until Hold is turned off. |
A short label next to each finger shows what it's playing. A finger can also be set to send two CCs instead of a note.
From a script
pad = UI::XYPad.new(scale: [36, 38, 40, 41, 43, 45, 47, 48],
glide_range: 2, y_cc: 74, device: dev)
pad.slot(5, x_mode: :cc, x_cc: 70, y_cc: 71, device: fx) # the 5th finger only
UI.pad(1, label: "Hold", type: :toggle) { |on| pad.hold = on }
pad.showOpen in the simulator ▶XYPad also appears in MIDI Devices, so you can send what it plays to more gear by patching it there.
Details: docs/XYPAD.md (Japanese)
Keys
A keyboard on the screen, 2 octaves from C3 by default. Keys also lights up the notes it receives, like a light-up MIDI keyboard, so you can see what your gear or DAW is playing.
| Touch | What it does |
|---|---|
| Press a key | Plays it (cyan while pressed). |
| Slide | Moving onto the next key plays that key, like a glissando. |
| Where you press | When the script sets velocity: :position, pressing nearer the front of the key plays louder. |
In MIDI Devices
- Keys → gear: what you play goes to that gear.
- Gear → Keys: notes coming in light the keys (orange). Patch a keyboard or PC to Keys to see what's playing. Keys doesn't pass incoming notes on; to hear the keyboard too, also patch it to a synth.
From a script
keys = UI::Keys.new(octaves: 2, low: 48, velocity: :position, device: MIDIDevices.amy) MIDI.route(MIDIDevices.usb_midi_host, keys) # light keys from an external keyboard keys.set_color([48, 52, 55], :blue) # show a chord or scale keys.showOpen in the simulator ▶
Details: docs/KEYS.md (Japanese)
Sequencer
A pattern sequencer for your whole set. A song has up to 16 lines (tracks, each with its own MIDI channel) and 16 patterns; a chain plays patterns in order. Each line can have its own length, so lines of different lengths make polyrhythms.
Timing and playback
- The Sequencer follows the MIDI clock it receives. Out of the box, Tempo is patched to it (clock only), so it plays at the Tempo screen's BPM. To follow other gear, patch that gear to Sequencer with Clock in MIDI Devices instead.
- Play / Stop on the Sequencer screen plays or stops the Tempo (and everything else following it) when the clock comes from Tempo. Tempo's own Play and a Start from external gear work too.
- Notes go wherever the Sequencer is patched in MIDI Devices, on each line's channel.
Patterns and chain
| Touch | What it does |
|---|---|
| Tap a pattern slot (1–16) | Switch to it: immediately when stopped, at the end of the current pattern when playing (the slot blinks while waiting). This turns the chain off. |
| Long-press a slot | Menu: Edit here (edit this pattern while another one plays), Copy, Paste, Clear, Length. |
| Chain | Tap to turn it on or off; long-press to edit the order and how many times each pattern repeats. |
| ◀ ▶ / 8·16 / Follow | Scroll through long lines by half a page, show 8 or 16 steps, and follow the playhead. |
Lines
| Touch | What it does |
|---|---|
| Tap a line header | Select the line (for REC and Follow). |
| M | Mute or unmute. |
| Long-press a line header | Line settings: Grid / Realtime, channel, steps, rate, bars, velocity, gate, quantize, record mode, program and bank, name, Copy / Paste / Clear for this line, Delete. |
| + Line | Add a line. |
Putting notes on the grid
The grid places the chord: the notes you played last on Keys or a keyboard patched to Sequencer (shown in the header; tap it to hear it).
| Touch | What it does |
|---|---|
| Tap an empty step | Place the chord, one step long. |
| Press an empty step and drag | Place the chord as long as you drag. |
| Tap a step with notes | Delete the notes starting there. |
| Press a step with notes and drag | Change their length. |
| Long-press a step with notes | Replace them with the chord. |
Recording
Select a line and tap REC to arm it; what you play while the Sequencer runs is recorded into the playing pattern. Choose overdub or replace and quantize in the line settings. Nothing is recorded while stopped.
Saving
- File (shows the song name,
*= unsaved changes): Save, Save new, Load, New, Delete (press twice), Close. Songs go to/sd/patterns/. - Your work is also autosaved: 5 seconds after the last change, every 60 seconds while you keep editing, and on Stop. It comes back after a restart.
From a script
seq = UI::Sequencer.current # the song on screen
seq.on_pattern { |e| UI.log("pattern #{e[:pattern]}") }
seq.showOpen in the simulator ▶Details: docs/SEQUENCER.md (Japanese)
Tombola
A spinning polygon with balls bouncing inside. Every time a ball hits a side, that side's note plays: harder hits play louder. Out of the box it plays a drum kit (GM drums on channel 10).
| Touch | What it does |
|---|---|
| Start / Stop (nav bar) | Start or stop. Starting with no balls adds three. |
| Tap inside the polygon | Add a ball there. |
| Drag | Turn the polygon by hand: it follows your finger and stops when you stop. Flick to throw the balls around. When you let go, it spins at its set speed again. |
The text in the corner shows the sides, speed (rpm), gravity, bounce and number of balls. Tombola keeps playing while you look at other screens.
In MIDI Devices
- Tombola → gear: the hits go there.
- Gear → Tombola: each note you hold adds a ball that plays that note; it goes away when you let go.
- Tempo → Tombola: Tempo's Play / Stop starts and stops it.
From a script
t = UI::Tombola.new(sides: 6, rotation: 12, gravity: 0.5, device: dev)
t.scale = [36, 38, 42, 45, 46, 49] # side N plays scale[N % size]
t.add_ball(color: :red)
UI.pad(1, label: "Faster") { t.rotation += 4 }
t.start
t.showOpen in the simulator ▶Also: gravity_mode (:down / :center / :none), bounce, friction, ball_size, channel, duration, on_hit.
Details: docs/TOMBOLA.md (Japanese)
Tempo
MIDoRI's master clock. It sends MIDI clock to every device it's patched to in MIDI Devices, and Start / Stop for the whole setup. It can also follow clock from other gear and pass it on.
| Touch | What it does |
|---|---|
| Tap the BPM | Tap tempo. TAP on the nav bar does the same. |
| Swipe the BPM | Up or right is faster, down or left is slower, 1 BPM per step. The number turns yellow while you swipe. |
| ▶ Play / ■ Stop | Sends MIDI Start or Stop. The BPM turns green while playing. |
| USB-H / USB-D / DIN / BLE | Where external clock comes from: USB gear, the computer, the DIN/TRS jack, Bluetooth. Ext: shows the BPM measured from it. |
| Sync | Follow the external clock (the BPM turns light blue). Gear patched from Tempo then follows it too. |
Clock is sent only to the devices Tempo is patched to (Tempo appears as a row in MIDI Devices). It keeps ticking whether or not you've pressed Play, as most gear expects.
From a script
MIDI.route(UI::Tempo, MIDIDevices.usb_midi_device) # clock to the DAW
UI::Tempo.bpm = 128
UI::Tempo.start # .stop / .tap / .sync = true
UI::Tempo.on_change { |bpm| UI.knob_set(1, bpm, notify: false) }Open in the simulator ▶Details: docs/TEMPO.md (Japanese)
AMY
The built-in synthesizer (AMY). It plays through the board's speaker, or headphones on the Tab5, and has two kinds of sound: FM (the 128 DX7 presets) and Synth (an analog-style synth with the 128 Juno-60 presets). The AMY tile on Home opens a panel for building sounds without a script.
The AMY panel
| Part of the screen | What it does |
|---|---|
| Tabs | One tab per part (a sound on a MIDI channel). + → + FM or + Synth adds one on the lowest free channel. Up to 8 tabs. |
| << < > >> | Previous / next preset, by 1 or 10. |
| Ch- / Ch+ | The part's MIDI channel (1–16). Parts on the same channel play together as a layer. |
| Del | Press twice (Sure?) to remove the part. |
| Envelopes | Drag the handles: A sideways, D sideways and up/down, S up/down, R sideways. Synth has Amp and Filter; FM edits one operator at a time (pick it with Op n). |
| Knobs | Synth: Cutoff, Reso, FltEnv, KeyTrk, Glide, Pan, Volume, Reverb. FM: Algo, Feedbk, OpLvl, Ratio, Cutoff, Reso, Volume, Reverb. (Reverb is shared by all parts.) |
| Keyboard | One octave to try the part on its channel. Oct- / Oct+ shift it. |
- To play AMY from other gear, patch that gear to AMY in MIDI Devices. AMY starts the first time something needs it.
- Speaker and headphone volume are on the Settings screen. The Tab5 switches to the headphone volume when you plug some in.
- Parts made on the panel aren't saved yet: running a script clears them.
From a script
amy = MIDIDevices.amy fm = amy.add_fm(channel: 0, patch: 128) # DX7 preset syn = amy.add_synth(channel: 1, patch: 5) # Juno-60 preset syn.cutoff = 900 MIDI.route(MIDIDevices.usb_midi_host, amy) # play it from a keyboardOpen in the simulator ▶
Details: docs/AMY_SYNTH.md · docs/AMY_PANEL.md (Japanese)
MIDI Devices (MIDI Info)
The patch bay. Rows are MIDI IN (where MIDI comes from) and columns are MIDI OUT (where it goes). A dot in a cell means everything from that row goes to that column. Patches you make here are saved right away and come back when you power on.
| Touch | What it does |
|---|---|
| Tap a cell | Patch or unpatch (all channels). Unpatching sends All Notes Off on the channels that were used, so nothing hangs. |
| Long-press a cell → Ch | Choose what passes: All, Clock (clock and Start / Stop only), channels 1–16 (several allowed), Off. Done or tapping outside closes it. |
| Long-press a cell → Filters | Chain MIDI filters (chords, arpeggios… from plugins) in the order you pick them. Long-press a chosen filter for its settings. |
| Long-press a row or column name | Device details: state, product name, transfer counters (handy when MIDI doesn't arrive). |
| Drag the grid | Scroll when there are more devices than fit. The names stay in place. |
| Top-left corner button | Show All, only Patched, or only Unpatched devices. |
Reading the grid
- Dot next to a row name: green = connected, gray = not connected. Line under a column name: yellow = standby (AMY before it starts).
- A patch whose device isn't connected shows as a gray ring. It starts working again as soon as the device comes back.
- Bottom-left of a cell: the channels it passes (
1-4,10,clk). Top-right:f2= a chain of 2 filters.
Devices you'll see
| Name | What it is |
|---|---|
| (product name) | USB MIDI gear, by name. Up to 4 through a USB hub. |
| PC | The computer or iPad on USB (midi_device mode). |
| SAM2695 | The SAM2695 unit: its General MIDI sounds and its DIN / TRS jacks. |
| BLE / (device name) | The iPad or Mac connected over Bluetooth, and BLE-MIDI gear MIDoRI connected to. |
| AMY | The built-in synth (OUT only). |
| Keys · Sequencer · Tombola | The on-screen instruments: both IN and OUT. |
| Tempo · XYPad | Send only (IN rows). |
| Script | The running script. Script's row is where the script's output goes; its column is what the script listens to. |
From a script
md = UI::MIDIDevices
md.patch(MIDIDevices.usb_midi_host, MIDIDevices.amy)
md.patch(MIDIDevices.usb_midi_device, MIDIDevices.sam2695, channel: [0, 9, :clock])
out = md.output # play into Script: goes wherever Script is patched
md.input.on(:note_on) { |m| out.note_on(m.note + 12, m.velocity) }
md.save # patches made by a script last until it ends, unless savedOpen in the simulator ▶Details: docs/UI_MIDI_DEVICES.md · docs/MIDI_FILTER_REGISTRY.md (Japanese)
Bluetooth
BLE-MIDI works both ways. As a Device, MIDoRI shows up on an iPad or Mac as a Bluetooth MIDI device (named "Midori Tab5" or "Midori CoreS3"). As a Host, it connects out to BLE-MIDI keyboards and adapters (WIDI and the like).
| Touch | What it does |
|---|---|
| Device On / Off | Be visible to an iPad or Mac. Below it: the name and state (advertising / connected). |
| Host On / Off | Connect out to BLE-MIDI gear. |
| Scan (nav bar) | Look for BLE-MIDI gear for 8 seconds. Press again to stop. |
| Tap a device in the list | Connect or disconnect. |
| x (right end) | Forget a known device. |
| Drag the list | Scroll. |
- The list shows connected devices first (dark blue), then known ones (
*), then ones the scan found (with signal strength). - Devices you've connected once reconnect by themselves while Host is on, unless you disconnected them yourself.
- The On / Off switches are saved. Connected devices appear in MIDI Devices (BLE for the iPad / Mac, the device name for gear), and Tempo can sync to BLE clock.
- On a Mac, connect from Audio MIDI Setup → MIDI Studio → Bluetooth; on an iPad, from your app's Bluetooth MIDI settings. If pairing fails after you reinstalled MIDoRI, delete "Midori" from the iPad's or Mac's Bluetooth devices and try again.
From a script
widi = BLE_MIDI_HOST.connect("WIDI") # by name; scans if needed
dev = MIDI::Device.new(MIDIDevices.ble_midi_host("WIDI"))
MIDI.route(MIDIDevices.ble_midi_device, MIDIDevices.amy) # iPad → AMYDetails: docs/BLE_MIDI.md (Japanese)