# Vibe Coding — Product Spec An [[AUv3]] MIDI effect plugin for iPad. MIDI in, humanized MIDI out. One job: take rigid, quantized MIDI and make it feel like a human played it. The plugin modifies existing MIDI events only. It does not add events (no ghost notes, no flams), does not generate MIDI, and does not process audio. Related: [[Videos/Just Found The Best Humanizing Plugin So Far|Mixed In Key "Human" plugin review]] — a similar concept for desktop DAWs, reviewed by [[Ozgun|Ozgun (Lunatik Rave)]]. ## Architecture Direct-per-dimension: each humanization dimension has its own independent control. No master Amount knob. Each knob governs how much of that specific type of humanization is applied. ## Mode Toggle Percussion / Melodic — a binary switch that changes the plugin's behaviour: - Percussion mode: 5 knobs active (Gate is hidden/disabled) - Melodic mode: 6 knobs active (Gate becomes available) The mode also affects parameter limits, algorithmic defaults (see Swing Subdivision below), and internal weighting (e.g., how the algorithm distributes variation across note ranges). ## Controls ### 1. Variation Timing displacement. How far notes scatter from their grid positions. At zero, notes sit on the grid. Turn it up, they loosen. The algorithm gives this musical shape internally (correlated offsets for nearby notes, louder notes stay more precise), but the user just sees one knob: tight to loose. Limits (asymmetric — early shifts are judged more harshly by the ear): - Percussion: -18ms early to +24ms late - Melodic: -24ms early to +32ms late ### 2. Swing Systematic offbeat displacement. Offbeat notes shift later, from straight to heavily swung. Limits: ratio equivalent 1:1 (straight) to 3:1 (heavy swing), capping offbeat delay at +25% of the beat pair. Includes a subdivision toggle: 8th notes or 16th notes. Defaults to 16th in Percussion mode, 8th in Melodic mode, but always overridable. ### 3. Velocity Dynamic variation. How much note-to-note velocity changes. At zero, every note hits at its programmed velocity. Turn it up, some hit harder, some softer. The algorithm weights stronger beat positions closer to original velocity internally. Limits: - Percussion: ±20 velocity units - Melodic: ±16 velocity units - Output always clamped to MIDI range 1-127 ### 4. Pocket Ahead/behind-the-beat bias. At centre (noon), no directional bias. Turn left: the whole performance pushes ahead of the beat. Turn right: it sits behind the beat. This is independent of Variation — Variation is the spread of the scatter, Pocket is where the centre of that scatter sits. Limits (asymmetric — behind-the-beat is more common musically): - -12ms ahead to +16ms behind ### 5. Drift Slow, bounded oscillation of the timing centre over longer periods. Drift is what prevents humanized loops from sounding like loops — the timing character breathes and evolves across an arrangement. At zero, no drift. Turn it up, more long-term movement. Drift is NOT accumulation. It oscillates around zero with bounded amplitude, so the performance never derails over long loops. Limits: - Amplitude: ±8ms - Period: 2-16 bars ### 6. Gate (Melodic mode only) Note length variation. At zero, note durations are unchanged. Turn it up, some notes hold slightly longer, others clip slightly shorter. Gives melodic lines a breathing, played quality. Hidden or disabled in Percussion mode. Limits: - -25% to +30% of original duration - Absolute minimum note length: 20ms (prevents zero-length / stuck notes) ### 7. Seed Seed controls the pseudo-random engine. Same MIDI input + same settings + same seed = same humanization result. Different seed = different "humanization fingerprint." Controls: - Lock: keep the current fingerprint - Re-roll: generate a new fingerprint Seed is about repeatability and recall (needed for bouncing/exporting), not about "more or less human." ### Additional Controls - Bypass: true bypass, exact MIDI passthrough - Swing subdivision toggle: 8th / 16th (adjacent to the Swing knob) - Mode toggle: Percussion / Melodic ## Parameter Limits Summary | Control | Percussion | Melodic | |---------|-----------|---------| | Variation | -18ms / +24ms | -24ms / +32ms | | Swing | 1:1 to 3:1 ratio | 1:1 to 3:1 ratio | | Velocity | ±20 | ±16 | | Pocket | -12ms / +16ms | -12ms / +16ms | | Drift | ±8ms, period 2-16 bars | ±8ms, period 2-16 bars | | Gate | — (disabled) | -25% / +30%, min 20ms | ## Default Values (Startup Preset) At plugin load, defaults are neutral and conservative: - Mode: Percussion - Variation: 20% - Swing: 0% (straight) - Swing Subdivision: 16th - Velocity: 18% - Pocket: 0ms (center) - Drift: 12% - Gate: 0% (inactive in Percussion, available in Melodic) - Seed Lock: ON - Seed: generated at instantiation, then fixed until Re-roll - Bypass: OFF ## Processing Order Transformations are applied in this fixed order: 1. Swing — structural grid reshaping, happens first 2. Pocket — directional bias applied to the swung grid 3. Drift — slow oscillation of the timing centre 4. Variation — random scatter around the (swung, pocketed, drifting) centre 5. Velocity — dynamic variation, applied after timing is finalised 6. Gate — note length variation, applied last (needs final start time to calculate duration) ## Latency / Lookahead Policy To shift notes earlier in time, the plugin needs a lookahead buffer. Policy for v1: - Standard mode uses fixed lookahead of 48ms (covers worst-case early-shift headroom + safety margin) - Low-latency mode uses 0ms lookahead and clamps all negative offsets to zero (notes can only shift late, never early) - The plugin reports current latency to the host so AUv3-aware hosts can compensate automatically - Latency mode changes are applied only while transport is stopped (avoids mid-playback latency jumps) ## Algorithmic Requirements The humanization should sound human, not random. The algorithm should handle these musical correlations internally without exposing them as controls: - Autocorrelation: nearby notes get correlated timing offsets (creating phrases, not chaos) - Velocity-timing coupling: louder notes get slightly less timing displacement - Late-gate coupling: notes displaced late get slightly shorter gate times - Register-aware variation (Percussion mode): lower notes (kick range) get less variation than higher notes (hi-hat range) - Stationary base variation: the statistical character of Variation stays stable over time. Drift alone adds long-timescale centre movement. This gives each knob one clear role. - Event-order safety: transformations must never produce invalid note-on/note-off ordering for the same pitch/channel pair. ## Acceptance Criteria 1. Bypass is bit-identical MIDI passthrough 2. Seed lock produces repeatable results 3. No dropped note-offs / no stuck notes 4. Percussion mode never changes note length 5. Negative-shift playback is correctly compensated at reported latency 6. All output velocities within MIDI range 1-127 7. All output note durations ≥ 20ms 8. No invalid note-on/note-off ordering after timing transforms ## What's Not In the App - No ghost notes, flams, or added MIDI events - No chord spread / strum timing - No position-aware behaviour (different feel on downbeats vs offbeats) — possible future addition - No master Amount / wet-dry knob - No groove templates or style presets (the knobs define the feel directly) - No audio processing (pure MIDI effect) ## Technical Platform - AUv3 MIDI effect plugin for iPadOS - Primary host targets: [[AUM]], [[Cubasis]], [[Logic Pro for iPad]], [[BeatMaker]] - [[GarageBand]] compatibility: TBD (verify MIDI effect slot behavior before claiming support) - Automatable AU parameters: Variation, Swing, Swing Subdivision, Velocity, Pocket, Drift, Gate, Mode - Seed controls are session actions (`Lock`/`Re-roll`) and are not required to be host-automated - Deterministic per seed (same input + same settings + same seed = same output) ## Interface Open question: the interface could be just the knobs and toggles on a clean layout, or it could include a live visualisation showing what the plugin is doing to the MIDI (dots on a grid showing timing scatter, velocity variation, swing lean, etc.). The visualisation would add feedback but isn't required for the product to work. To be decided during development. ## Build Steps 1. Write spec (this document) 2. Install [[Xcode]] (free from Mac App Store) 3. Create Xcode project with AUv3 MIDI effect extension target 4. Build MIDI passthrough (skeleton — MIDI in, unchanged MIDI out) 5. Add seven parameters as AUv3 parameters 6. Implement each humanization algorithm one at a time 7. Build the UI (knobs, toggles, bypass, seed lock/re-roll) 8. Test in iPad Simulator for UI and basic logic only (no full host-chain MIDI validation) 9. Create [[Apple Developer Program]] account ($99/year — needed for real-device testing and App Store) 10. Test on physical iPad with host apps 11. App Store submission ## Sources Parameter limits are engineering inferences informed by: - [Microtiming and groove perception research (Frontiers in Psychology)](https://www.frontiersin.org/journals/psychology/articles/10.3389/fpsyg.2015.01232/pdf) - [Expert performance microtiming and groove (PMC)](https://pmc.ncbi.nlm.nih.gov/articles/PMC5050221/) - [Swing ratio and timing context (Scientific Reports)](https://www.nature.com/articles/s41598-019-55981-3) - [Micro-variation ranges (Scientific Reports 2025)](https://www.nature.com/articles/s41598-025-12604-4) - [Sample-accurate MIDI timing in AUv3](https://cp3.io/posts/sample-accurate-midi-timing/) - [AU latency reporting (Apple Developer)](https://developer.apple.com/library/archive/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/TheAudioUnit/TheAudioUnit.html) - [MIDI 1.0 message specification](https://midi.org/summary-of-midi-1-0-messages)