All projects

Now building · 2026

Companio

A cross-platform mobile accompaniment app. The product is a style-aware live band; the current milestone is a C++ music core proven on desktop.

Founder / systems engineer

  • C++
  • JUCE
  • MIDI
  • React Native (planned)

Problem

Singers need a band that stays with them in real time. Cloning a piano-lesson game or guessing genre from a solo voice is the wrong product. The hard problem is listening — pitch, tempo, and conservative harmony — on a tight latency budget.

What I built

  • Build a JUCE-free clock, pattern engine, and musical state that can later wrap into React Native via JSI.
  • Play piano, bass, and drums from MIDI style packs (Gospel, Afrobeat, Pop, R&B) with live key, chord, and intensity controls.
  • Follow the singer conservatively: sticky tempo, optional auto-key, style-grammar chords that change on downbeats.

Architecture

flowchart LR
  mic[Mic] --> dsp[DSP worker]
  dsp --> pitch[Pitch and tempo]
  pitch --> state[MusicalState]
  ui[Desktop UI] --> queue[CommandQueue]
  queue --> state
  state --> patterns[PatternEngine]
  patterns --> mix[Mixer]
  mix --> out[Headphones]

Outcomes

  • Desktop host plays a locked click plus a 2-bar band at a chosen key and tempo.
  • Live controls apply on the next bar downbeat without allocations on the audio thread.
  • On-device YIN pitch, sticky tempo, count-in, and local recording exist on the desktop harness. Not in stores yet.

The product, not the prototype

Companio is a style-aware live accompanist. You pick Gospel, Afrobeat, Pop, or R&B and a key, put on headphones, and sing. The band is supposed to stay with you — piano, bass, and drums from MIDI style packs, not a canned backing track.

The shipped product is a cross-platform mobile app. React Native will own screens and setup. A shared C++ core owns the audio clock. JavaScript never renders sound. Web is a later second backend (AudioWorklet), not the product.

The current milestone is that core, proven on a thin macOS JUCE host. There is no App Store listing and no public demo URL. If it is not musical on the desktop, wrapping it for iOS will not save it.

What exists today

  • Sample-accurate clock and a click; 2-bar patterns that wrap without dropping a 16th.
  • Style packs: Gospel (Low / Medium / High) plus Medium grooves for Afrobeat, Pop, and R&B.
  • Live key, mode, force-chord (I / IV / V / vi), intensity, mute, and volume. Musical changes apply on the next bar downbeat.
  • On-device listening on a worker thread: YIN pitch, sticky tempo that slews gently, optional auto-key. Manual tempo and key still win.
  • Conservative chord grammar that proposes on downbeats and stays put when confidence is low.
  • Local recording, 1- or 2-bar count-in, and a warning when output does not look like headphones.

The audio callback does not parse JSON, touch the filesystem, or start threads. Packs preload on the message thread; the audio thread swaps a pointer.

What I will not claim

This is not Perfect Piano, nor iRealPro. It is not “sing anything and an LLM figures out the song.” Genre is a user choice. Chord changes are sticky and slightly late on purpose — musicians hate a band that finds a new chord every bar.

Latency belongs on-device. Bluetooth hands-free paths and cloud inference blow the budget. Headphones are a day-one constraint because the mic otherwise hears the band.

Next

Keep proving the band on desktop, then wrap the same library for iOS and Android. The public API stays small: prepare, process, setState, start / stop.