SnoreLog
Snoring Detection in Sleep Environments
Detecting snoring patterns in noisy sleep environments.
- Acoustic Signal Processing
- Audio Classification
- Temporal Pattern Analysis
- Year
- 2026
- Role
- Solo — concept, audio pipeline, app
- Status
- In development
How three approaches evolved to better detect snoring in real-world recordings.

- V1 — Amplitude-based: simple, but mistakes background noise for snoring.
- V2 — CNN: 99.3% test accuracy, undone by sampling-rate bias, evaluation flaws and poor real-world generalization.
- V3 — Acoustic + temporal: a two-stage algorithm that checks how a sound looks and whether it repeats like breathing.
TL;DR
Developed a snoring detection system for real-world sleep environments, exploring amplitude-based detection, CNN classification, and acoustic signal processing.
Despite achieving 99.3% initial test accuracy, the CNN failed in real-world conditions. Further investigation revealed a sampling-rate bias and flaws in the evaluation pipeline.
To address these limitations, I developed a two-stage detection algorithm combining acoustic features and temporal regularity, which identified repetitive snoring patterns in real-world recordings.
01
Research Objective
Background
I wanted to record and monitor my own snoring during sleep, particularly to identify significant snoring episodes without listening to hours of recordings.
However, real-world sleep environments contain many interfering sounds — clocks, conversations, birds, appliances and other ambient noise.
The challenge was not simply to record sound, but to distinguish snoring from background noise and identify meaningful snoring patterns.
Research Question
How can snoring be reliably told apart from other sounds in noisy, real-world sleep environments?
Objectives
Research — Snore Detection
Distinguish snoring from non-snoring sounds in real-world bedroom recordings.
Service — Snoring Monitoring (Not covered on this page. Built into the SnoreLog app.)
Measure nightly snoring levels and track changes over time.
View app screens

Home 
History 
Night report 
Episodes, ready to replay Screens filled with sample nights.

02
Development Journey
Three approaches were explored, each addressing limitations identified in the previous iteration.
01Amplitude-Based DetectionLimitedIdentified the limitations of amplitude-based detection in noisy environments.
Hypothesis
Snoring could be identified as relatively loud acoustic events.
Methodology
Implemented a simple threshold-based detector. The app sampled the recording's amplitude every 200 ms and treated anything above a fixed threshold as a potential snoring event.
Sounds that came back within 10 seconds were merged into the same event, so that one snore was not counted many times.
Results
In use, the detector fired on many environmental sounds — clocks, conversations and birds — because they also crossed the threshold. Measured on real recordings, it failed in both directions:
- False positives: three of four recordings of clinking sounds were logged as snoring.
- Missed snoring: in a quieter 15-minute stretch of a real night, the threshold fired once — on a sound that was not snoring — and missed every snore below it.
- Merged snoring: breaths are 3–5 s apart, always inside the 10-second merge window, so continuous snoring collapsed into a single event and the night scored 95, "Great".


Limitations
A single threshold measures how loud the room is, not what made the sound. It cannot adapt when the background changes, and it has no notion of a snore's shape.
Takeaway
Amplitude alone is insufficient for distinguishing snoring from environmental noise.
The next iteration focused on the acoustic characteristics of snoring rather than signal intensity.
02CNN-Based ClassificationInvalidatedUncovered a sampling-rate bias and evaluation flaws behind 99.3% initial test accuracy.
Hypothesis
A convolutional neural network could learn the distinctive time-frequency patterns of snoring and classify them more accurately than amplitude thresholding.
Methodology
1. Dataset
Used a public snoring dataset from Kaggle (Khan, 2019): one-second clips, split 70 / 15 / 15 into training, validation and test sets.
| Category | Clips |
|---|---|
| Snoring | 500 |
| Non-snoring | 500 |
| Total | 1,000 |
2. Feature extraction
Converted each clip into a 64-band mel spectrogram. The pipeline assumed every recording was 48 kHz — an assumption later found to be wrong.
| Parameter | Value |
|---|---|
| Assumed sampling rate | 48 kHz |
| FFT size | 1,024 (21 ms) |
| Hop length | 256 (5.3 ms) |
| Mel bands | 64 |
| Input dimension | 64 × 188 |

3. Model architecture
Designed a lightweight CNN for eventual on-device use. Six channel configurations were compared, prioritising low computational cost.
| Parameter | Value |
|---|---|
| Architecture | Lightweight CNN + global average pooling |
| Channels | 12 → 12 |
| Parameters | 1,489 |
| Model size | ~6 KB |

4. Data augmentation
| Technique | Configuration |
|---|---|
| Noise injection | SNR 10–30 dB |
| Pitch shifting | ±2 semitones |
| Time shifting | ±20% |
| Volume scaling | 0.1–1.5× |
Each of the 700 training clips gained four augmented copies. The final training set held 3,720 clips: these 3,500, plus 22 one-second segments of my own clinking recordings (as non-snoring) and matching extra snoring copies, each with their augmentations. Augmentation was applied only after the split, so no test clip had a copy in training.
Results
- 99.3%
- initial test accuracy (149 of 150)
- 98.2%
- mean test accuracy across 30 training runs
- 1 / 900 s
- classified as snoring in a real 15-minute night
On a real 15-minute sleep recording, the model labelled only one of 900 seconds as snoring. In the same segment, the final detector (V3) found 32 snoring events; these have not yet been confirmed by manual annotation.
This discrepancy motivated a deeper investigation into the training and evaluation pipeline.
Failure Analysis
1. Spurious correlation — sampling-rate bias
The dataset mixes 44.1 kHz and 48 kHz recordings, and the pipeline treated all of them as 48 kHz without resampling. A 44.1 kHz clip therefore ended in 0.08 s of padded silence and had its frequencies read about 9% too high. More importantly, the sampling rate was strongly correlated with the label.
| Class | 44.1 kHz | 48 kHz |
|---|---|---|
| Non-snoring | 450 | 50 |
| Snoring | 58 | 442 |
A rule using only the sampling rate would score about 89% on the full dataset. The CNN might have learned this preprocessing artifact rather than relying only on acoustic characteristics.

Controlled experiment
All 150 test clips were properly resampled to 48 kHz and evaluated with the already-trained model.
| Evaluation condition | Accuracy |
|---|---|
| Original preprocessing | 99.3% |
| Correct sampling rate at inference | 68.7% |

The model is sensitive to preprocessing artifacts. The 68.7% is not the expected performance of a model retrained on a corrected pipeline.
2. Model selection bias
The test set was used to choose the final architecture among six candidates, which compromised the independence of the final test score.
A checkpoint bug compounded this: a shallow copy of the model's state dictionary kept changing as training continued, so the "best" snapshot was not preserved. Some earlier figures — including a 100% result — cannot be treated as independent estimates of generalisation.
3. Real-world generalisation
The CNN continued to perform poorly on real sleep recordings. Differences in background noise, distance to the microphone, sound intensity and room acoustics plausibly contributed, but the experiments did not isolate domain shift from the preprocessing and evaluation problems.
Takeaway
High benchmark accuracy does not guarantee real-world performance.
Unintended correlations, inconsistent preprocessing and evaluation design can significantly distort reported performance. This motivated an approach built on domain-specific acoustic characteristics and temporal context.
03Acoustic & Temporal AnalysisPromisingDeveloped a two-stage detection algorithm for repetitive snoring patterns.
Hypothesis
Snoring is characterised not only by its acoustic properties but also by its temporal relationship to breathing: snores recur with each breath, while most bedroom noises happen once. Requiring both a snore-like sound and a breathing-like rhythm should therefore separate snoring from one-off noises.
Methodology
A lightweight, two-stage rule-based detector that runs on the phone. Stage 1 finds sounds with snore-like acoustics; Stage 2 checks whether they repeat like breathing.

Stage 1 — Acoustic feature analysis
Adaptive noise floor. Instead of a fixed threshold, the background level is estimated from the quietest moments (15th percentile) of a rolling 90-second window, so the detection threshold follows changes in the room.
Feature extraction. Six characteristics from FFT-based spectral analysis and timing:
| Feature | Criterion | Weight |
|---|---|---|
| Low-frequency energy | Share of energy in 60–300 Hz | 0.28 |
| Tonality | Not flat like noise (spectral flatness) | 0.18 |
| High-frequency energy | Little energy in 1–8 kHz | 0.15 |
| Duration | About one breath (0.7–2.5 s) | 0.15 |
| Harmonicity | Harmonic peak structure | 0.14 |
| Onset | Attack pattern | 0.10 |
Snore score = Σ (feature score × weight)
Events scoring at least 0.55 pass Stage 1. Two hard rules reject sounds with excessive high-frequency energy or a noise-like flat spectrum. A sweep over 0.30–0.95 on nine real recordings showed 0.55 to be the strictest value that still keeps every snoring recording.

Stage 2 — Temporal pattern validation
Stage 1 judges each sound alone, and non-snoring sounds can share its acoustics. Stage 2 examines the timing between candidates.
| Parameter | Criterion |
|---|---|
| Inter-event interval | 1.2–10 seconds |
| Minimum repetitions | 4 events |
| Coefficient of variation | ≤ 0.35 |
CV = standard deviation of intervals / mean interval
A lower CV means more consistent repetition. Four events are required because three unrelated sounds can land at even spacing by chance; four means three intervals must agree.

Results
Stage 1 — Public dataset
On the 1,000 Kaggle clips, Stage 1 alone reached 80.0% accuracy (78.7% on the CNN's 150-clip test split) without any supervised training. Most misses came from clips filled with sound from start to end, which leave the adaptive floor no quiet moment to measure against.
Full system — Real recordings
The Kaggle clips are isolated one-second recordings, so they cannot test Stage 2, which needs a sequence of events. The complete system was therefore evaluated on real recordings.
| Recordings | Amplitude (V1) | Stage 1 only | Both stages (V3) |
|---|---|---|---|
| 9 short clips (5 snoring, 4 clinking) | 6 / 9 | 6 / 9 | 9 / 9 |
| 15 minutes of a real night | 1 event | 58 candidates | 32 snores in 2 bouts |

These results are promising, but the night has not been manually annotated, so precision and recall on real recordings are not yet measured. The detector costs about 0.039% of one CPU core — roughly 11 seconds of compute for an eight-hour night (measured on a laptop, not yet on a phone).
Limitations
- Isolated snoring events. At least four consecutive events are required, so isolated or highly irregular snoring may be missed — acceptable for the current goal of finding sustained episodes rather than every single snore.
- Periodic environmental noise. Regular sounds such as a ticking clock could still satisfy the temporal criteria; none were among the test recordings.
- Quantitative validation. Manually annotated real-world recordings are needed to measure precision, recall and F1-score. The weights were set by hand from a few recordings.
Takeaway
Temporal context provides information that individual acoustic features cannot.
Combining frequency-domain analysis with temporal validation identified repetitive snoring in real recordings without a trained neural network.
03
Key Findings
- 01
Data quality matters more than benchmark accuracy
The CNN reached 99.3% test accuracy, but the sampling rate was correlated with the labels. Preprocessing and methodology have to be validated before a score can be interpreted.
- 02
Real-world generalisation requires careful evaluation
Performance on isolated clips did not carry over to continuous recordings of real nights. Evaluation must reflect the acoustic conditions and temporal structure of the application.
- 03
Temporal context can improve detection
Single sounds can be hard to tell from environmental noise — a clinking sound had a snore's spectrum. How sounds repeat over time adds the missing information.
- 04
Algorithm design should reflect the application
Rather than maximising a public benchmark, the final approach targets meaningful snoring episodes in continuous recordings, which led to a lightweight, task-specific detector.
04
Future Work
Quantitative evaluation
Build a manually annotated set of real sleep recordings and measure precision, recall and F1-score for the complete system.
Hybrid detection
Combine acoustic features, a lightweight neural network retrained on a corrected pipeline, and temporal validation to improve robustness across recording environments.
Snoring intensity estimation
Estimate the relative acoustic intensity of detected episodes from energy, duration and spectral characteristics — kept separate from clinical measures of sleep-disordered breathing.
On-device monitoring
Validate whole nights on a phone, including battery consumption, and generate automatic recording summaries.
Conclusion
This project began as an attempt to monitor my own snoring and evolved into an investigation of audio classification, dataset bias and real-world detection.
Across three iterations, I explored the limits of amplitude-based detection, found hidden weaknesses in a CNN's evaluation, and built a lightweight algorithm that combines acoustic features with temporal regularity.
Reliable systems require not only effective algorithms, but also rigorous evaluation and a clear understanding of the environments in which they operate.
Built with
- Python
- PyTorch
- torchaudio
- NumPy
- FFT
- CNN
- Dart
- Flutter
Deep dives
Individual pieces of this project, written up on their own.