Embedded Gunshot Detection: Offline Gunshot Recognition SDK for Public SafetyNEW
The Value of Gunshot Detection: Scenarios and Workflow
In public safety, every second between an incident and a response matters. Gunshots carry a unique acoustic fingerprint — and unlike cameras, microphones work in darkness, around corners, and across open spaces. From a single campus to a whole city, acoustic sensing adds a continuous awareness layer where eyes are sparse.
The Signature of a Gunshot
Below is a real gunshot recording (including multiple shots) — waveform (top) and Mel spectrogram (bottom). The millisecond-scale spikes and broadband vertical streaks are clearly visible:

Audio samples (real recordings — press play):
🔊 Gunshot (real sample)
🔊 Another gunshot recording
Millisecond-scale onset — — the leading edge of the shock is virtually instant; energetic analysis of the onset is the first piece of evidence
Echo tail — — the blast reflects off buildings and terrain; the decaying echo pattern is a second, environment-based signature
Discrimination from lookalikes — — fireworks rise more slowly with whistle-like tails; car backfires form clean pulse trains without complex echoes
An industry honesty note: firecrackers are acoustically close to gunshots — a well-known hard problem. Multi-microphone cooperation and event aggregation across nodes are the practical ways to raise reliability.
How Recognition Works: Preprocessing → Features → Algorithms
1. Shock event — onset-triggered detection
2. Feature verification — transient fingerprint plus echo structure
3. Multi-microphone localization (optional) — arrival-time differences across nodes estimate the event location
4. Push and platform linkage — command center pop-ups, map pins, camera retrieval, ticket creation
All decisions run on the edge device; audio stays on-device by default.
City-Scale Deployment
Deploying across a city is a system engineering problem — the six-step path:
1. Site survey — priority areas and ambient noise profiling
2. Device selection and installation — height, orientation, power
3. Acoustic calibration — per-site baseline and sensitivity
4. Networking and commissioning — private network or cellular backhaul
5. Platform integration — event APIs, map, ticketing
6. Operations — uptime monitoring, false-alarm review, site refinement
Start with a pilot cluster, validate, then scale.
Edge sensing layer — — on-device gunshot decision and uplink policy
Network layer — — wired / 4G / 5G backhaul, cache-and-forward on outage
Platform layer (private deployment capable) — — event aggregation, multi-site correlation, storage, open interfaces
Application layer — — command platform, guard desks, ticketing, dashboards
Sites cluster around intersections, schools and commercial districts — typical installation 4–6 m height, away from strong noise sources, spacing planned per coverage tier.
Phase P1 pilot (2–4 weeks) → P2 expansion (2–3 months) → P3 city-wide and long-term operations. Node uptime target ≥99%; event-to-platform delivery ≤5 s.
Campus and Commercial District Solutions
Campuses and commercial districts share a structural gap: vast open areas cannot be permanently watched by human eyes.
1. Acoustic event — edge decision with location pin
2. Guard desk pop-up — time, location, clip reference
3. Visual verification — nearest camera auto-retrieved
4. Plan activation — patrol dispatch, broadcast, alarm linkage
5. On-site handling — status reported back
6. Record and review — archive for drills
"Verify before dispatch" keeps guard resources from chasing false alarms.
Manual discovery takes minutes to tens of minutes; acoustic sensing delivers events within seconds — plus traceable records for drills.
Accuracy and Performance
Platform and Hardware Requirements
Sensing nodes run the model on-device within 0.2–1 MB (INT8); nodes are typically pole-mounted with PoE or solar/battery power; networking over private fiber/LTE/5G.
C API and Embedded Integration
The gunshot detection library exposes a concise streaming C API: the caller just keeps feeding 16 kHz mono PCM; framing, Mel preprocessing and model inference run internally, and frame-level probabilities are aggregated by the alarm strategy into event callbacks.
Full interface declaration (gunshot_detect.h):
/**
* gunshot_detect.h — 枪声识别统一接口
*
* 封装 Mel 预处理 + 推理引擎 + 报警策略, 内部模型消费线程处理音频。
* 与录音模块 (audio_capture.h) 相互独立: 调用者自行决定音频来源
* (录音回调 / wav 文件 / 网络流), 通过 gunshot_detect_feed 送入, 数据任意大小。
*
* 用法 (实时录音模式):
* gunshot_detect_t *d = gunshot_detect_create(mgk_path, NULL, NULL);
* gunshot_detect_set_listener(d, on_frame, on_onset, on_offset, NULL);
* gunshot_detect_start(d); // 启动内部模型消费线程
* audio_capture_start(rec, capture_cb, d); // 录音回调里调 gunshot_detect_feed
* ...
* gunshot_detect_stop(d); // 排空缓冲, 停止线程
* gunshot_detect_destroy(d);
*
* 用法 (wav 文件模式):
* gunshot_detect_t *d = gunshot_detect_create(mgk_path, NULL, NULL);
* gunshot_detect_set_listener(d, on_frame, on_onset, on_offset, NULL);
* gunshot_detect_start(d);
* 循环读文件: gunshot_detect_feed(d, pcm, n); // 任意数据大小
* gunshot_detect_stop(d);
* gunshot_detect_destroy(d);
*/
#ifndef GUNSHOT_DETECT_H
#define GUNSHOT_DETECT_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* 识别事件 (报警策略输出, 用于事件结束回调) */
typedef struct {
float start_time; /* 事件开始时间 (秒) */
float end_time; /* 事件结束时间 (秒) */
float confidence; /* 事件置信度 */
float max_confidence; /* 事件内最大帧置信度 */
int frame_count; /* 事件持续帧数 */
} gunshot_detect_event_t;
/* 帧级回调: 每帧识别结果 (模型线程内执行) */
typedef void (*gunshot_detect_frame_cb_t)(float gunshot_prob, float timestamp,
void *user_data);
/* 事件开始回调: 策略判定枪声事件开始, 只有开始时间 */
typedef void (*gunshot_detect_onset_cb_t)(float start_time, void *user_data);
/* 事件结束回调: 策略判定枪声事件结束 (或停止识别时未结束的事件), 完整事件信息 */
typedef void (*gunshot_detect_offset_cb_t)(const gunshot_detect_event_t *event,
void *user_data);
typedef struct gunshot_detect_s gunshot_detect_t;
/* 创建/销毁; alarm_name/alarm_params 可传 NULL (用默认策略及参数) */
gunshot_detect_t *gunshot_detect_create(const char *mgk_path, /* 模型文件路径 (必填) */
const char *alarm_name, /* 报警策略名, NULL=默认 */
const char *alarm_params); /* 策略参数 key=val,key=val, NULL=默认 */
void gunshot_detect_destroy(gunshot_detect_t *det);
/* 设置事件回调 (create 后调用, 也可在运行中调整); 不需要的回调传 NULL */
void gunshot_detect_set_listener(gunshot_detect_t *det,
gunshot_detect_frame_cb_t on_frame,
gunshot_detect_onset_cb_t on_onset,
gunshot_detect_offset_cb_t on_offset,
void *user_data);
/* 启动/停止识别: 启动内部模型消费线程 / 排空缓冲后停止线程 */
int gunshot_detect_start(gunshot_detect_t *det);
void gunshot_detect_stop(gunshot_detect_t *det);
int gunshot_detect_is_running(gunshot_detect_t *det);
/* 设置事件识别策略 (可在运行中调整) */
int gunshot_detect_set_alarm(gunshot_detect_t *det, const char *alarm_name,
const char *alarm_params);
/* 送入 PCM 数据 (16bit 单声道 16kHz), 线程安全, 任意数据大小 */
int gunshot_detect_feed(gunshot_detect_t *det, const int16_t *pcm, int num_samples);
#ifdef __cplusplus
}
#endif
#endif /* GUNSHOT_DETECT_H */
A minimal WAV-inference demo (excerpt; the full file ships at src/gunshotDetect/c/gunshot_demo.c):
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "gunshot_detect.h"
#define DEFAULT_MGK "gunshot_detect_v7.mgk" /* 模型文件 */
#define DEFAULT_WAV "test_gunshot.wav" /* 16kHz 单声道 16bit PCM */
#define FEED_CHUNK 16000 /* 每次送入 1 秒音频 */
/* 帧级回调: 每帧输出枪声概率 (约 1 秒一帧) */
static void on_frame(float gunshot_prob, float timestamp, void *user_data)
{
(void)user_data;
printf("%8.2fs gunshot=%.4f\n", timestamp, gunshot_prob);
}
/* 事件开始回调: 策略判定枪声事件开始 */
static void on_onset(float start_time, void *user_data)
{
(void)user_data;
printf("[EVENT] gunshot start at %.2fs\n", start_time);
}
/* 事件结束回调: 应用层可据此做后续统计或分级响应 */
static void on_offset(const gunshot_detect_event_t *ev, void *user_data)
{
(void)user_data;
printf("[EVENT] gunshot end at %.2fs (dur=%.2fs, conf=%.3f, frames=%d)\n",
ev->end_time, ev->end_time - ev->start_time,
ev->confidence, ev->frame_count);
}
static int read_wav_pcm(const char *path, int16_t **pcm, int *n, int *sr); /* 完整实现见源文件 */
int main(void)
{
gunshot_detect_t *det;
int16_t *pcm = NULL;
int num_samples = 0, sample_rate = 0;
int pos;
if (read_wav_pcm(DEFAULT_WAV, &pcm, &num_samples, &sample_rate) != 0)
return 1;
/* 1. 创建识别器: 模型文件 + 默认报警策略 (NULL) */
det = gunshot_detect_create(DEFAULT_MGK, NULL, NULL);
if (!det) return 1;
/* 2. 注册回调 (均为可选) */
gunshot_detect_set_listener(det, on_frame, on_onset, on_offset, NULL);
/* 3. 启动内部模型消费线程 */
gunshot_detect_start(det);
/* 4. 分块送入 PCM; 实时录音时改在录音回调里 feed */
for (pos = 0; pos < num_samples; pos += FEED_CHUNK) {
int n = num_samples - pos;
if (n > FEED_CHUNK) n = FEED_CHUNK;
gunshot_detect_feed(det, pcm + pos, n);
}
/* 5. 停止并销毁 */
gunshot_detect_stop(det);
gunshot_detect_destroy(det);
free(pcm);
return 0;
}
Build and run:
$(CC) gunshot_demo.c -I. -L. -lgunshotdetect -lpthread -lm -o gunshot_demo
./gunshot_demoConclusion
Gunshot detection is transient recognition at its hardest — and its most valuable. If you are building public-safety, campus or city sensing solutions, an online trial with deployment methodology support is available.