karankhatavkar/ak47-acoustic-rul-simulated
AK-47 Acoustic Run-to-Failure (RUL) Simulation Dataset A synthetic Run-to-Failure dataset for Remaining Useful Life (RUL) estimation of an AK-47's recoil spring from gunshot audio. Because real run-to-failure recordings of a wearing firearm are practically impossible to collect, this dataset is generated by a physics-based Digital Twin that takes a small set of real, healthy gunshot recordings and mathematically simulates the acoustic signature of mechanical wear over thousands… See the full description on the dataset page: https://huggingface.co/datasets/karankhatavkar/ak47-acoustic-rul-simulated.
AK-47 Acoustic Run-to-Failure (RUL) Simulation Dataset
A synthetic Run-to-Failure dataset for Remaining Useful Life (RUL) estimation of an AK-47's recoil spring from gunshot audio. Because real run-to-failure recordings of a wearing firearm are practically impossible to collect, this dataset is generated by a physics-based Digital Twin that takes a small set of real, healthy gunshot recordings and mathematically simulates the acoustic signature of mechanical wear over thousands of rounds.
The core physical assumption: as the recoil spring fatigues and loses its spring constant, the return-to-battery velocity drops, which lengthens the time gap between the muzzle blast ("Bang") and the bolt closing ("Clank"). This cycle time (delta-T) is the wear biomarker, and a sigmoid health curve maps it to a 0–100% health (life remaining) label.
Code & Reproducibility
The full pipeline that generates this dataset — audio preprocessing, the physics-based Digital Twin simulator, and the CWT-scalogram / tabular-feature extraction — is open-sourced at [github.com/karankhatavkar/ak47-acoustic-rul](https://github.com/karankhatavkar/ak47-acoustic-rul).
Repository Structure
.
├── real_recordings/ # Raw, real AK-47 single-shot WAV recordings (the source audio)
├── seed_audio/ # Cleaned & trimmed healthy "seed" clips + ground-truth manifest
│ └── ak47_health_manifest.txt
├── simulated_audio/ # Synthetic run-to-failure WAVs + master log + per-seed graphs
│ ├── S1/ … S71/ # WAVs bucketed by seed (ak_47_S{seed}_P{point}.wav)
│ ├── simulation_master_log.csv
│ └── sim_graphs/
├── cwt_scalograms/ # CWT scalogram images (224×224 PNG) of every simulated clip
│ └── S1/ … S71/ # PNGs bucketed by seed, names mirror the WAVs
└── features/
└── xgboost_features.csv # Hand-crafted acoustic features for every simulated clipNote on the `S{seed}/` sub-folders. The simulated clips are bucketed into one sub-folder per seed (S1,S2, …S71, ~460 files each) inside bothsimulated_audio/andcwt_scalograms/. This is required because the Hugging Face Hub caps every directory at 10,000 files, and each of these sets has ~30.6 k clips. The seed id is embedded in every filename (ak_47_S{seed}_P{point}), so a file's bucket is simplyS{seed}—simulation_master_log.csvstores the bare filename and the bucket is derived from it.
Folder descriptions
Source of the Original Audio
The real gunshot recordings in real_recordings/ are sourced from the public [Gunshot Audio Dataset by Emrah Aydemr on Kaggle](https://www.kaggle.com/datasets/emrahaydemr/gunshot-audio-dataset) (the AK-47 class). All synthetic data in this repository is derived from those healthy recordings; no real worn-out / failed firearm audio exists or is used.
How the Dataset Was Built
The dataset is produced by a three-stage pipeline: (1) preprocessing the real audio into clean labelled seeds, (2) simulating run-to-failure trajectories from each seed, and (3) deriving model-ready representations (CWT scalograms and tabular features).
1. Preprocessing (real recordings → labelled seeds)
Applied to every file in real_recordings/ to produce seed_audio/ and the health manifest:
- Load each recording at 44.1 kHz mono.
- Locate the gunshot event with a pattern-based anchor finder rather than a naive loudest-peak search. It combines normalized RMS energy (sustained power) and onset strength (percussive transients) into a single score (
rms_norm × onset_norm), smooths it with a Gaussian filter (~50 ms) to favour a sustained event over a single click, then backtracks from the score peak to the moment the event started (where the score first falls below 10% of its peak). - Crop a fixed window around that anchor — 100 ms before and 900 ms after (a clean ~1.0 s clip) — and save as
seed_{original_name}.wav. - Manually drop one ambiguous record (
seed_1 (14).wav) that could not be reliably anchored. - Measure the cycle time (delta-T) for each seed from its onset envelope: the Bang is the global onset maximum; the Clank is the strongest onset peak in a 50–150 ms window after the Bang.
delta_T = (clank_time − bang_time)in ms. (The seed set averages ≈ 93.9 ms.) - Map cycle time → initial health with the logistic (reverse-sigmoid) degradation model and write
ak47_health_manifest.txt:
$$H(t) = \frac{100}{1 + e^{0.19\,(t - 120)}}, \qquad H(t)=0 \text{ for } t \le 40 \text{ or } t > 130$$
2. Data Simulation (Digital Twin run-to-failure)
For each labelled seed (starting from its measured base cycle time T_base), a physics-based simulator generates a full degradation trajectory shot-by-shot. It is built on three coupled models (full spec in the Simulation Parameters table):
- A. Kinematic wear model — the actual cycle time at shot
iis the base time plus an exponential wear trend and a heteroscedastic mechanical jitter (the gun rattles more as it wears):
$$t{final}(i) = T{base} + \underbrace{\alpha\, e^{\beta i}}{\text{wear trend}} + \underbrace{\mathcal{N}\!\big(0,\; \sigma{base} + \gamma i\big)}_{\text{mechanical jitter}}$$
- B. Ideal health model (ground truth) — the reverse-sigmoid mapping cycle time to health, so the spring holds tension then fails rapidly:
$$H{ideal}(t) = \frac{100}{1 + e^{K\,(t - T0)}}$$
- C. Dynamic variance model (label noise) — a Gaussian envelope that injects realistic uncertainty into the health label, maximal during the mid-life transition phase and near-zero at the healthy/failed extremes:
$$\sigma{health}(t) = P{noise}\, e^{-\frac{(t - P{time})^2}{2 W^2}}, \qquad H{final} = \mathrm{clip}\!\big(H{ideal} + \mathcal{N}(0, \sigma{health}),\, 0,\, 100\big)$$
The shot loop runs until the wear trend pushes the cycle time past failure (T_base + wear_trend > 145 ms). A fixed random seed (42) makes the whole simulation reproducible.
Audio rendering. For each simulated shot that is kept, the seed waveform is time-stretched with a librosa phase-vocoder at rate T_base / t_target (longer target cycle time → slower playback), which acoustically lengthens the Bang→Clank gap to match the simulated wear. To keep the dataset to a manageable size, every 5th shot is rendered to a WAV (simulated_audio/S{seed_id}/ak_47_S{seed_id}_P{point}.wav); the label of every rendered shot is recorded in simulation_master_log.csv, and a trajectory plot per seed is saved under sim_graphs/.
3. Derived representations
Both derived feature sets are computed from simulated_audio/ using the labels in simulation_master_log.csv.
a. CWT scalograms (`cwt_scalograms/`) — for 2D-CNN image regression:
- Load at 22.05 kHz; zero-pad or truncate to a fixed 1.5 s.
- Continuous Wavelet Transform with a complex Morlet wavelet (
cmor1.5-1.0) over 128 scales (geomspace(1, 100)). - Take the coefficient magnitude → amplitude-to-dB (ref = max) → normalize to 0–255 → vertical flip → resize to 224×224 (cubic) → apply the JET colormap → save as PNG.
b. Tabular acoustic features (`features/xgboost_features.csv`) — for classical ML / XGBoost:
- Load at 44.1 kHz and extract 15 features per clip:
zcr_mean— mean Zero-Crossing Rate (proxy for gas blow-by / turbulence).spectral_kurtosis— kurtosis of the mean STFT spectrum (proxy for mechanical rattle).mfcc_1 … mfcc_13— means of the first 13 MFCCs (timbre / receiver resonance).- Each row is joined with
seed_file_name,sample_file_name,delta_T_ms, and the targetpercent_life_remaining.
Simulation Parameters
Expected trajectory behaviour: health stays locked near 100% in the early phase (low variance), spreads into a vertical "cloud" through the mid-life transition (max spread ≈ ±20% at 2σ around 110 ms), then crashes toward 0% past ~120 ms as the noise envelope tightens — confidently labelling failed weapons as near-zero health.
Usage (load_dataset)
All three modalities share one label file (simulation_master_log.csv) and the clips live in S{seed}/ buckets, so the cleanest way to load is to build the dataset from the master log and let 🤗 datasets decode the audio / images lazily. The bucket is derived from the filename:
import re
import pandas as pd
from datasets import Dataset, Audio, Image
from huggingface_hub import snapshot_download
repo = snapshot_download("karankhatavkar/ak47-acoustic-rul-simulated", repo_type="dataset")
def bucket(fn): # 'ak_47_S12_P3.wav' -> 'S12'
return f"S{re.search(r'_S(\\d+)_', fn).group(1)}"
log = pd.read_csv(f"{repo}/simulated_audio/simulation_master_log.csv")
log["audio"] = log["sample_file_name"].map(lambda f: f"{repo}/simulated_audio/{bucket(f)}/{f}")
log["scalogram"] = log["sample_file_name"].map(lambda f: f"{repo}/cwt_scalograms/{bucket(f)}/{f[:-4]}.png")
ds = (
Dataset.from_pandas(log)
.cast_column("audio", Audio()) # 1D-CNN: raw waveform
.cast_column("scalogram", Image()) # 2D-CNN: CWT scalogram
)
# target column: percent_life_remaining
# Tabular / XGBoost features (no audio decoding needed):
tab = pd.read_csv(f"{repo}/features/xgboost_features.csv")Intended Use
- RUL / prognostics regression — predict
percent_life_remainingfrom audio. - Three model families this dataset supports out of the box:
- Tabular / XGBoost on
features/xgboost_features.csv. - 2D CNN on
cwt_scalograms/images. - 1D CNN on the raw
simulated_audio/waveforms.
Important Caveats
- This is synthetic data produced by a physics-inspired model; the degradation is simulated, not measured from a real worn firearm. It is intended for prognostics method development and benchmarking, not as ground truth for real-world firearm wear.
- Time-stretching alters the temporal structure of the seed clip; acoustic features reflect that transformation rather than independently recorded worn-gun audio.
Citation
If you use this dataset, please credit this repository, the code repository, and the original source audio (Gunshot Audio Dataset, Emrah Aydemr, Kaggle).
