
Own productAndroid
FartGuard
an awkward noisea DJ set
It listens for one sound, then covers it or turns it into a live DJ set.
In short
A meme app with serious insides: an on-device detector catches one specific sound and either instantly covers it with a masking sound or turns it into a track in 8 genres.
- A joke idea as a testing ground for hard things: on-device ML, real-time audio, generative music and viral sharing mechanics.
- Two detectors: a fast band-energy one (Goertzel) and a fine-tuned YAMNet on TensorFlow Lite, trained on 2,272 positive AudioSet clips.
- Remix: the key follows the sound’s pitch, the set is written as a score from bar one, and “Remix again” gives a new take.
- 15 recorded decisions, honest ones included: “8 real genres, not 20 advertised” and three changes of release track.
208
genres the engine actually implements
2,272
positive clips for fine-tuning YAMNet
15
recorded decisions
Why
It started as “a meme app for masking bathroom sounds”, with personas like Meme-lord Misha, Shy Sveta and Office Oleg. The joke turned out to be a great testing ground: on-device sound recognition, audio under 200 ms of latency, and music that has to be composed in seconds.
Solution
- 01
Listen
A GO button, a live spectrum ring, optional background listening. Microphone audio at 16 kHz never leaves the phone.
- 02
Cover
50 sounds in five categories: memes, music, nature, masking and voiceover.
- 03
Or remix
A set in one of 8 genres with the captured sound as the lead instrument. Vertical video export with a visualiser.
- 04
Show off
9 ranks from “Ninja 🥷” to “Extinction Level Event ☄️”, peak decibels, daily streaks and a “Beat this” share card.
Try it
Decisions
- 0006
Eight implemented genres, not twenty advertised
Why. The design named 20 genres while the engine had builders for 8, and it silently fell back to trap. Now the picker offers only what exists, and the other 12 names are a roadmap that must not be described as a feature.
Rejected: Keeping 20 in the picker: the same bug with a longer menu.
- 0014
The sample leads: the key follows it, the set is a score
Why. A report came in: “the sample doesn’t make it into the remix”. There were four causes, from 16-bit PCM read as float to a random key up to an octave away from the sound. The fix: the key comes from the sample’s pitch, the composer writes the whole set as a score, and the sample becomes the lead instrument.
- 0010–0012
The release track changed three times, and each change is recorded
Why. First a push went to testers, then to production, then back to internal testing until the store listing is ready. Reversed decisions are kept: they show why the current one is what it is.
- 0003
One engine, two hosts
Why. The music engine is plain scripts without modules, so the same files run in the app’s WebView and in the browser lab. And now on this site too.
How it is built
Expo and React Native in TypeScript, state in Zustand with MMKV. The default detector is a Goertzel band-energy filter; the second is YAMNet, fine-tuned in Colab and Kaggle notebooks on AudioSet clips and packaged as a 7.8 MB TensorFlow Lite model. Music comes from a generative Tone.js engine in a hidden WebView. Telemetry goes to PostHog directly, without the SDK. Every push to main builds in EAS and GitHub Actions.
Status
Builds ship to Google Play internal testing; the app has not yet been run on physical devices, and there are no store screenshots yet. You can hear the music engine right here.
Want more? Switch the reading depth to 30 min.