All posts
webdevjavascripttypescriptproductivity

I built an app that decodes what your dog is saying โ€” in one night

JacoboยทMarch 30, 2026ยท5 min read

My friend's dog, Luna, is a French Bulldog who whines every night around 2 AM. He couldn't figure out if she was anxious, bored, or just demanding attention. He'd been googling "what does dog whining mean" for months, getting generic answers that didn't apply.

I thought: there's an app for this. Then I looked. There actually isn't โ€” not a clean, modern one. So I built it.


The problem

Dog owners spend enormous amounts of time and money trying to understand their pets. Vet bills, behaviorist consultations, dozens of YouTube videos. But most of the time, the question is simple: is my dog stressed? bored? excited?

The information to answer this exists. Dog vocalization research is well-documented โ€” specific bark patterns, frequency ranges, and duration profiles map reliably to emotional states. Stressed dogs bark at higher pitches with irregular pauses. Bored dogs have monotone repetitive patterns. Excited barks are fast and high-energy.

Nobody had wrapped this in a UI a regular person could actually use.


The core insight

I didn't need a full ML model. I needed a signal classifier โ€” something that could extract acoustic features from a short audio clip and pattern-match against known vocalization profiles.

Web Audio API gives you frequency data natively via AnalyserNode.getByteFrequencyData(). With that, I can measure:

  • Dominant frequency (pitch โ†’ high = excited/stressed, low = bored/hungry)
  • Frequency variance (irregular = anxious, monotone = bored)
  • Amplitude envelope (sharp spikes = excited/alert, sustained = anxious/stressed)
  • Bark rate (fast bursts = excitement/alert, slow = bored)

Here's the core analysis function:

function analyzeVocalization(buffer: AudioBuffer): BehaviorAnalysis {
  const ctx = new OfflineAudioContext(1, buffer.length, buffer.sampleRate);
  const analyser = ctx.createAnalyser();
  analyser.fftSize = 2048;
  
  const freqData = new Uint8Array(analyser.frequencyBinCount);
  analyser.getByteFrequencyData(freqData);
  
  const dominantFreq = getDominantFrequency(freqData, buffer.sampleRate);
  const variance = getFrequencyVariance(freqData);
  const barkRate = detectBarkRate(buffer);
  
  return classifyEmotionalState({ dominantFreq, variance, barkRate });
}

The classifier maps these three signals to five states: excited, anxious, stressed, bored, hungry. With confidence scores. It's not perfect ML โ€” it's good heuristics. And heuristics that are explainable are actually better for this use case, because you can tell the user why the AI reached its conclusion.


What surprised me

Pet parents are hungry for specificity. The demo I showed to three dog owners got the same reaction: "Oh, this actually tells me something actionable." They didn't care about model accuracy โ€” they cared that it gave them a hypothesis to test. "Maybe Rocky is stressed by the construction noise next door." That's enough.

The empty state is 50% of the product. I spent more time on the "no recordings yet" screen than on the core analyzer. It had to feel inviting, not blank. A small animated waveform, a playful headline, a clear CTA. First impressions in consumer apps are everything.


What I'd do next

  • Real ML model: Train on the Barks DB dataset with a lightweight CNN
  • Push notifications: "Luna has been whining for 3 minutes โ€” want to check in?"
  • Multi-dog households: Profile management for families with multiple dogs
  • Vet integration: Export a PDF behavior report your vet can actually use

Try it

The app is live at traini.limed.tech. It's free. No account required. Just record your dog and see what they're trying to tell you.

If your dog is anything like Luna โ€” they probably just want dinner.

โ€” Jacobo

๐Ÿพ Try Traini

Record your dog's sounds and find out exactly what they're feeling โ€” free, no account needed.

Analyze My Dog โ†’