MoshBox

This is the operating manual for MoshBox. It is a live datamosh instrument: one video input, one moshed output, a small grammar of packet operations, and an eight-bank frame tape.

Its behaviour is informed by Interstream v2.0 by Jonas Bers / Signal Culture, but the implementation is new.

Signal flow

Camera or clip ──► encoder ──► mosh grammar ──► decoder ──► HDMI
                                      ▲                │
                                      └── frame tape ◄─┘

The encoder and decoder form one continuous session. Sources are normalised to the scene size before encoding, so switching between them does not reset the codec. A source change is an event the grammar sees: the SourceSwitch op makes it a clean cut or a smear that drags the previous reference into the new picture.

The frame tape sits alongside the output. It stores decoded pictures for time-domain repeat and, in Mosh mode, can feed them back through the encoder.

Setting up

You need:

  • One USB UVC camera or capture device (the main source)
  • An HDMI display, mixer or capture card
  • A MIDI controller for hands-on control; the default map is for a Korg nanoKONTROL2
  • A power supply suitable for your Raspberry Pi device (5V / 2.5 A for Pi 3 or Zero 2, 5.1 V / 3.0 A for Pi 4)

Connect the camera, HDMI and MIDI, then power up. If no camera is attached, MoshBox plays the Autumn Sun over the river Spree, so the engine still has something to work with.

The output resolution is baked into the image. The standard Raspberry Pi 3 build is 640×480, a 4:3 SD image for analogue chains. The Pi 4 build is 1280×720, a 16:9 HD Ready image. Capture, scene and display share one resolution, so the picture is not rescaled on the hot path.

Sources

The camera is the shipping source and hot-swaps: plug a capture device in after boot and MoshBox opens it. The clip is the fallback. It is the first video file by name in the data folder, looped, and it is the drop point for footage without a rebuild. There is no playlist and no USB watching.

  • s switches to the next source. On the nanoKONTROL2, the TRACK buttons do this.
  • c selects the camera.
  • C cycles capture devices.
  • l jumps straight to the clip.
  • The SOURCE SWITCH pot sets what happens at a source change: 0 is smear, 1 is clean. The default is clean.

Sources are cover-cropped to the scene's shape before encoding, so a camera and a clip of different shapes arrive at the encoder as the same format.

Switching sources mid-mosh is the point of the single-stream design. With the SOURCE SWITCH pot toward smear, the new source inherits the old reference and the change melts; with clean, a keyframe is forced and the cut is hard.

The mosh grammar

MoshBox treats the encoded stream as a list of packets and runs a program of ops over it. A program is an ordered list of ops with parameters, a seed and a tempo.

Group Ops What they do
Reference DropKey, ForceKey, Normalize Withhold keyframes, force a clean re-anchor, or flush the references
Repeat RepeatDelta, Stutter, Bloom Replay deltas so motion accumulates
Damage Corrupt Damage packet payloads without touching their headers
Order Hold, Shuffle, SortByMotion, Reverse Reorder packets inside the window
Rhythm Pulse Open and close the mosh on the beat
Source SourceSwitch Choose a clean cut or a cross-source smear at a source change

The default program is SourceSwitch + DropKey + RepeatDelta. DropKey withholds keyframes so the decoder predicts from a stale reference; RepeatDelta replays delta packets so the motion keeps accumulating. That is the continuous mosh. Press mosh (space, or SOLO 1 on the nanoKONTROL2) to engage it.

The program runs a small state machine. Idle is a clean pass-through, Active is the mosh, and Recovering lets a clean reference through while repeat and damage ops are quiesced. That is why Normalize can snap the picture back to a clean reference.

Presets can carry other combinations of these ops. The default program is not the only program.

Mosh modes

MoshBox has a continuous mosh and two optional layers:

  • Continuous — the default program. A steady pour with no clock.
  • Rhythm — adds Pulse, which opens and closes the mosh on the beat. The PULSE DIV and PULSE HOLD faders shape the gate. Toggle it with p or SOLO 3.
  • Motion — the source's own motion drives RepeatDelta.count, so the mosh stretches harder when the picture moves. Toggle it with m or SOLO 4; the MOTION AMOUNT and MOTION MAX pots set the depth and ceiling.

The layers can be combined. Continuous is the foundation; rhythm and motion are layers on top. Rhythm uses the clock: the tempo can come from the internal BPM, MIDI clock, or tap tempo. Presets capture the tempo.

Frame tape

The grammar's repeat ops work in the packet domain: they re-apply motion, so the picture stretches. The frame tape is the other kind of repeat. It stores decoded pictures, so it can play a moment again exactly — or feed that moment back through the current program.

The tape has eight banks. Each bank can hold a loop of 1 to 120 frames (4 seconds at 30 fps). It runs at 30 fps, independent of the render rate. A bank is captured from the live history; the default loop is the most recent 4 seconds.

Banks

  • Press an empty bank (1–8, or REC 1–8) to capture the last loop and start playing it.
  • Press a filled bank to recall it.
  • Press the active bank again to toggle between the loop and live passthrough.
  • x captures into the active bank, overwriting it.
  • k clears the active bank.
  • j freezes or resumes the playhead.
  • y toggles loop / live.
  • i cycles the loop mode: forward, ping-pong, reverse.
  • , and . change the loop length.
  • < and > move the loop window.
  • The MARKER RIGHT button restarts the active loop.

Wet, dry, clean and mosh

  • Wet is the decoded output — the show, mosh included.
  • Dry is the encoder input — the source before the mosh.
  • Clean displays the stored frame directly, with no generation loss.
  • Mosh feeds the stored frame back through the encoder, so the current program chews the memory.

u switches between wet and dry. They are captured on the same tick, so the switch is a frame-exact A/B at the same playhead. n switches between clean and mosh playback. In Mosh mode the dry track is often the more interesting one: it re-performs an old moment under the current settings rather than replaying the old result.

The loop window

The loop window is a slice inside the captured bank. The loop length sets its size, and the position moves its centre: 0 is the earliest window, 1 is the latest. The window is per bank, so switching away and back restores where you left it. A fresh capture starts on the most recent window; shortening keeps the window's end fixed, so a one-frame loop freezes the newest frame.

Recording

Clean mode keeps recording the live pipeline, so you can capture a new moment while watching an older loop. Mosh mode pauses recording, because the encoder input is the tape itself and recording would capture the feedback path.

Banks share the frame pool rather than copying it, so eight overlapping loops are cheap. If the pool fills, the oldest captured bank is evicted.

Presets capture the tape's transport — loop length, loop mode, track and Clean/Mosh — but never the frames. Bank contents are performance material, not configuration.

Order modes

The order layer reorders packets inside the window. It adds about eight frames of video latency; control latency is unaffected.

Mode What it does
none No reordering
Reverse Reverses the packet order in the window
SortByMotion Reorders packets by motion
Shuffle Shuffles the packet order
Hold Holds one moment's motion; it can read as a freeze

Use o or MUTE 6 to cycle the modes. MUTE 1–5 select a mode directly.

Presets

A preset captures the whole program: the ops in order, their parameters, the seed, the tempo, the encoder settings and the tape transport. It never captures the tape's frames. Recalling a preset and feeding the same input reproduces the same output.

  • REW and FF recall presets, and the MARKER SET button saves.

Presets live in the app's data folder.

Encoder

Codec, bitrate and GOP are live controls.

  • CC36 cycles the codec: mpeg4 → mpeg2video → h263p → libx264 → libvpx.
  • CC17 halves and doubles the bitrate. A lower bitrate is coarser and blooms more; a higher bitrate is finer.
  • CC21 steps the GOP up and down by five frames.

A codec change rebuilds the decoder and forces a keyframe, so the stream recovers immediately. An invalid setting rolls back to the previous working encoder.

The default codec is mpeg4. Change codecs in discrete steps; sweeping through them is not useful.

MIDI — nanoKONTROL2 default map

MoshBox opens a MIDI port by name. The default match is nanokontrol; set MOSHBOX_MIDI to use a differently named or virtual port.

The default map splits by function: the channel strips play, the SOLO row is the mosh and tape layer, the MUTE row is the order layer, the REC row is the eight tape banks, and the master/transport section navigates presets and sources.

Faders

Fader CC Function
1 0 Repeat count — how many times each delta is replayed
2 1 Stutter rate — probability a delta is stuttered
3 2 Bloom burst — how many recent deltas are replayed as a burst
4 3 Corrupt rate — probability a payload is damaged
5 4 Corrupt amount — fraction of the payload zeroed
6 5 Pulse division — subdivisions per beat
7 6 Pulse hold — how many subdivisions stay open
8 7 Stutter count — copies emitted when a delta stutters

Pots

Pot CC Function
1 16 Source switch — 0 smear, 1 clean
2 17 Bitrate
3 18 Tape length — 1 to 120 frames
4 19 Motion amount — depth of motion-driven repeat modulation
5 20 Motion max — ceiling the modulation can reach
6 21 GOP — keyframe interval
7 22 Tape window position — 0 earliest, 1 latest

Pot 8 (CC 23) is unbound.

Buttons

Button CC Function
SOLO 1 32 Toggle the mosh
SOLO 2 33 Normalize
SOLO 3 34 Toggle the rhythm layer
SOLO 4 35 Toggle motion modulation
SOLO 5 36 Cycle the codec
SOLO 6 37 Reset (normalize)
SOLO 7 38 Toggle wet / dry
SOLO 8 39 Toggle clean / mosh
MUTE 1 48 Order: none
MUTE 2 49 Order: Reverse
MUTE 3 50 Order: SortByMotion
MUTE 4 51 Order: Shuffle
MUTE 5 52 Order: Hold
MUTE 6 53 Cycle order
REC 1–8 64–71 Tape banks 1–8
PLAY 41 Toggle loop / live
STOP 42 Freeze or resume the playhead
REW 43 Previous preset
FF 44 Next preset
REC (transport) 45 Capture into the active bank
CUE 46 Cycle the tape loop mode
MARKER SET 60 Save preset
MARKER LEFT 61 Clear the active bank
MARKER RIGHT 62 Restart the active loop
TRACK left 58 Previous source
TRACK right 59 Next source

MUTE 7 and MUTE 8 (CC 54/55) are unbound. The default map leaves three of the 51 controls empty on purpose.

The buttons are momentary CCs; each press fires once.

Not every fader has something to drive in the default program. The default program is SourceSwitch + DropKey + RepeatDelta, so the repeat count, source switch, encoder, mosh, order, tape and preset controls are live immediately. The Stutter, Bloom and Corrupt faders become active when a preset carries those ops; the Pulse faders need the rhythm layer, and the motion pots need motion modulation.

Bindings live in assets/control-map.json; edit the map and relaunch, with no rebuild. The map is validated strictly, so a bad binding is reported rather than silently ignored.

Troubleshooting

Symptom What to try
No picture Check the HDMI connection. If no camera is attached, make sure there is a video file in the data folder for the clip fallback.
Camera not detected Reseat the capture device; C cycles capture devices; check that it is UVC-compatible.
The mosh is not engaging Press mosh (space or SOLO 1). Check the HUD: Idle is a clean pass-through.
The image goes clean after a moment Normalize or the Recovering state has re-anchored the picture. Press mosh again.
Rhythm does not gate Turn on the rhythm layer (p or SOLO 3) and check the clock and BPM.
Motion does nothing Turn on motion (m or SOLO 4) and raise the MOTION AMOUNT and MOTION MAX pots.
An order mode freezes the picture Hold is a freeze by design; choose another order mode.
A source switch is a hard cut The default is clean. Turn the SOURCE SWITCH pot toward smear.
A source switch smears when you want a cut Turn the SOURCE SWITCH pot toward clean.
A codec change glitches Expected. The decoder rebuilds and forces a keyframe.
MIDI is not responding Check the controller is connected; MoshBox matches the port name nanokontrol. Set MOSHBOX_MIDI for another device.
A control does nothing The default program is SourceSwitch + DropKey + RepeatDelta. Stutter, Bloom and Corrupt need a preset that includes the op; the Pulse faders need the rhythm layer.
A tape bank does nothing An empty bank captures on the first press; x captures into the active bank. Check the HUD for tape off if the tape was disabled.
The tape plays but the mosh does not Clean playback is selected. Press n or SOLO 8 to switch to Mosh.
The tape window will not move The loop length is the same as the bank size. Shorten the loop, then move the window.
Mosh mode stops recording Expected. Mosh playback uses the encoder for the tape, so recording pauses until you return to Clean or live.
The tape uses too much memory Reduce MOSHBOX_TAPE_FRAMES, set MOSHBOX_TAPE_DRY=0, or disable the tape with MOSHBOX_TAPE=0.

Specifications

Input 1× USB UVC camera or capture device
Output HDMI: 640×480 4:3 SD on Pi 3; 1280×720 16:9 HD Ready on the 720 build
Processing Encoder → mosh grammar → decoder
Frame tape 8 banks, 1–120 frames (4 s at 30 fps), wet/dry, clean/mosh, forward/ping-pong/reverse
Control MIDI (nanoKONTROL2 default); keyboard on desktop builds
Presets Ops, parameters, seed, tempo, encoder settings, tape transport
Platform Raspberry Pi 3 / Pi 4
Power 5 V / 2.5 A / 5.1 V 3.0 A recommended

Credits

MoshBox's behaviour is informed by Interstream v2.0 by Jonas Bers / Signal Culture.