Severity: Medium. Crashes happen after all the processing is done, and wrong output is produced silently.
Findings (all reproduced)
| input |
result |
-fl 0 / -fl -5 / -fh 0 |
ValueError: filter critical frequencies must be greater than 0, a raw traceback raised after every frame has been processed |
13–27 frames with -fl 100 -fh 800 |
ValueError: The length of the input vector x must be greater than padlen… (sosfiltfilt padding). The frame_count > 12 guard is too low; 28 frames works |
| ≤ 12 frames with a filter |
the filter is skipped silently |
-fl ≥ Nyquist |
prints Warning: … skipping filter and writes unfiltered audio |
-fh above Nyquist |
quietly clamped to 0.99·Nyquist (acceptable, but should be reported up front) |
The fps trap
The README notes that MIT's sample AVIs report ~30 fps although they were captured at 2200 fps. If a user forgets --fps 2200:
- Nyquist becomes 15 Hz, so a typical
-fl 100 becomes the "skipping filter" case above, and the output is unfiltered;
- the WAV is written at a 30 Hz sample rate, which most players can't play.
Nothing warns about this. Also, save_wav(..., int(fps)) truncates fractional rates (29.97 → 29).
Suggested fix
- Validate everything in
main() before reading frames:
-fl > 0, -fh > 0, -fl < Nyquist;
- error, rather than warn, when
-fl ≥ Nyquist;
- print the effective band.
- Replace
frame_count > 12 with the real requirement: compute padlen from the SOS and fall back to sosfilt (or padtype=None) or a clear error for shorter clips.
- Warn loudly when the effective fps is below ~500 Hz, e.g. "Visual Microphone needs high-speed video; the container reports 30 fps — did you mean --fps 2200?".
- Write the WAV with
round(fps), or resample to a standard rate (e.g. 8 or 16 kHz) with scipy.signal.resample_poly while keeping the native rate as an option. Many players reject 2200 Hz WAVs.
Acceptance criteria
Severity: Medium. Crashes happen after all the processing is done, and wrong output is produced silently.
Findings (all reproduced)
-fl 0/-fl -5/-fh 0ValueError: filter critical frequencies must be greater than 0, a raw traceback raised after every frame has been processed-fl 100 -fh 800ValueError: The length of the input vector x must be greater than padlen…(sosfiltfiltpadding). Theframe_count > 12guard is too low; 28 frames works-fl≥ NyquistWarning: … skipping filterand writes unfiltered audio-fhabove NyquistThe fps trap
The README notes that MIT's sample AVIs report ~30 fps although they were captured at 2200 fps. If a user forgets
--fps 2200:-fl 100becomes the "skipping filter" case above, and the output is unfiltered;Nothing warns about this. Also,
save_wav(..., int(fps))truncates fractional rates (29.97 → 29).Suggested fix
main()before reading frames:-fl > 0,-fh > 0,-fl < Nyquist;-fl ≥ Nyquist;frame_count > 12with the real requirement: computepadlenfrom the SOS and fall back tososfilt(orpadtype=None) or a clear error for shorter clips.round(fps), or resample to a standard rate (e.g. 8 or 16 kHz) withscipy.signal.resample_polywhile keeping the native rate as an option. Many players reject 2200 Hz WAVs.Acceptance criteria