Blog · November 6, 2026

Sound Event Detection for Alerts

A microphone hears everything: doors, dogs, the dishwasher, and once in a while the sound you actually care about. This guide covers how to turn short clips into alerts people keep reading: writing the sounds as plain options, setting thresholds so doubt goes to a log instead of a pager, and feeding a continuous stream through a 10-second limit.

Saina · November 6, 2026 · 6 min read

A microphone in a shop at night hears the fridge, a car outside, the shutter rattling, and maybe once a year a window breaking. Sound event detection is the job of saying which of those happened. For an alert system, the hard part is staying quiet for everything else, so the one alert that matters still gets read.

This guide covers writing the sounds as options, keeping doubtful clips away from the pager, and feeding a stream into a model that takes clips of at most 10 seconds. The examples use Saina Helm 2 Omni, but most of it applies to any audio classifier.

What you are actually deciding

Research on sound event detection often means labelling sounds with start and end times in a long recording. Alerting usually needs less: is the sound I care about present in this short clip? That is clip-level tagging, and the time resolution is your window length.

Two shapes cover most alert rules:

The second shape is usually better for alerts, for a reason covered next.

Write the sounds plainly, and include the confusions

The Omni model card's advice for audio: say in the state what the clip is, name the sounds plainly in the options, and ask short, literal questions about what is audible. In practice:

The Breaking glass preset in the Studio playground is built this way. Its state is a home security microphone at 3 a.m., and the options are shatter, slam, footsteps and bark, so a bang that is not glass has somewhere to go.

The care-home case has the same structure. Ask which of cough, speech, alarm and snoring can be heard in a clip from a bedside microphone at night, and write a rule that wakes the night nurse for coughing fits, not for every sound in the room. That is a prompt for a person to go and look: Omni's card lists final, unreviewed medical decisions as out of scope.

Thresholds: what goes to the pager and what goes to the log

Alert fatigue is a thresholding problem: if every clip that might contain glass pages someone, the pages stop being read.

With "mode": "decision" and a threshold, a multi_choice answer lists in selections only the sounds whose score reached the threshold, and comes back with reason: "below_threshold" when none did. A yes_no or single_choice answer that falls short comes back with no selection and a reason (below_threshold, below_margin or tie) instead of a guess. That gives you three outcomes to route:

  1. Target sound accepted: alert.
  2. Nothing accepted, or the target scored in a middle band you define: log the clip for review in the morning, or send it to a low-priority queue a person scans. No pager.
  3. A known harmless sound accepted: log it or drop it.

Some rules that tend to help, all to be tuned on your own recordings:

A request

Illustrative; the request shape follows the API docs, and the base64 string is cut short.

import base64, requests

def as_data_url(path, mime='audio/wav'):
    return f'data:{mime};base64,' + base64.b64encode(open(path, 'rb').read()).decode()

r = requests.post('https://api.saina.run/v1/ask',
    headers={'Authorization': f'Bearer {API_KEY}'},
    json={
        'model': 'saina-helm-2-omni-0.8b',
        'mode': 'decision',
        'threshold': 0.8,
        'state': 'The clip is a short recording from a home security microphone '
                 'in a kitchen at 3 a.m. Nobody should be in the building.',
        'audios': [as_data_url('window_0412.wav')],
        'questions': {
            'heard': {
                'type': 'multi_choice',
                'question': 'Which of these sounds can be heard in the clip?',
                'options': {'glass': 'Glass shattering or breaking',
                            'slam': 'A door slamming',
                            'drop': 'A heavy object dropped on the floor',
                            'alarm': 'An alarm or siren',
                            'voice': 'A person speaking or shouting'},
            },
        },
    })

heard = r.json()['answers']['heard']
if 'glass' in (heard.get('selections') or []):
    page_on_call(heard['memberships'])
elif heard['memberships']['glass'] > 0.3:          # middle band: an example to tune
    queue_for_review(heard['memberships'])

memberships holds a score for every option whether or not it was selected, so the middle band is your own rule on top of the model's threshold.

Windowing a stream into 10-second clips

Omni takes audio clips of up to 10 seconds, 10 MiB each, as base64 data URLs in the request body. A longer clip is refused, never cut, so a live stream has to be split before it is sent.

What the published numbers say

The Omni card reports a held-out audio evaluation: 4,120 clips from 21 public sources, 5,572 single-answer questions, with 69.4% answered correctly overall. Two sources are close to alerting work:

Source What is asked Questions Correct
FSD50K everyday sound events 345 77%
VocalSound laughs, coughs, sneezes and other vocal sounds 219 73%

Questions have 2 to 8 options, so chance differs by source, and these are clean public datasets, not your microphone in your room. Record a few dozen clips of the real target sounds and the real background where the microphone will hang, label them, and measure before you connect a pager.

When something else is the better choice

A decision model fits when the sounds you care about change from site to site, when you want to describe them in words instead of retraining, or when the sound is one input among several (time of day, which door sensor fired, who should be in the building) in the same request.

Try it

With a free account, the Studio playground has Breaking glass and Care monitor presets. Runs are charged in credits, and the cost is shown first. The model card is at run-saina/saina-helm-2-omni-0.8b.