This release delivers a 2.3x inference speedup for Google Perch v2 on default configurations and fixes several range filter issues that could cause incorrect species filtering after geomodel installation. The model gallery gains a standalone BirdNET Geomodel v3.0 card, and the Analysis settings page is reorganized into dedicated bird and bat sections with a new confirmation-based false positive filter for bat detections.
New Features
Perch v2 Inference Performance
Multi-model inference is now serialized so only one model runs at a time, eliminating memory bandwidth contention on resource-constrained hardware. The ONNX Runtime thread default is fixed to use all available CPU cores instead of falling back to single-threaded execution when threads=0. On a Raspberry Pi 5, this cuts default-config Perch v2 inference from 630ms to 270ms, a 2.3x improvement (#3088).
BirdNET Geomodel v3.0 Model Gallery Card
BirdNET Geomodel v3.0 is now available as a standalone entry in the model gallery with proper attribution and license metadata. The gallery Available tab is split into "Acoustic Classifiers" and "Geomodels" sections, making the layout extensible for future model types. Installed geomodel cards show the upstream URL and license badge (#3091).
Analysis Settings: Bird and Bat Sections
The Analysis settings page is reorganized into dedicated Bird Detection and Bat Detection sections with independent change tracking. A reusable false positive filter component uses stepped dot indicators and i18n-ready level names. A warning banner appears when the false positive filter is set to Off, encouraging users to enable filtering (#3097).
Bat Detection: Confirmation-Based False Positive Filter
Bat detection gains its own confirmation-based false positive filter, separate from the bird filter and the ultrasonic validation filter introduced in the previous release. The filter uses three levels (Off, Moderate, Strict) matched to the bat model's fixed 50% overlap. Bat models now correctly use settings.Bat.Threshold instead of falling back to the BirdNET threshold, preventing legitimate bat detections from being filtered when the BirdNET threshold is set higher (#3094).
Bug Fixes
Range Filter
- Species list not refreshed after geomodel install - installing a geomodel from the model gallery reinitialized the ONNX backend but never rebuilt the species inclusion list. The processor kept using the stale list from startup until the next daily rebuild at midnight (#3086).
- "Allow species without range data" toggle had no effect - enabling PassUnmappedSpecies did not add unmapped classifier species (~314 for BirdNET V2.4) to the inclusion list. The species count shown in the UI stayed the same and unmapped species were silently blocked (#3099).
- Geomodel auto-selection overriding user config - an explicit user-configured range filter model (e.g.,
rangefilter.model: legacy) was silently replaced by auto-selection logic. Now gated on empty model field so explicit config is respected (#3087). - Duplicate species in range filter output - species appearing in both range filter results and include/config lists were counted twice. Added deduplication in the legacy path (#3087).
Multi-Model Analysis
- Buffer overrun monitor using BirdNET-specific calculations for all models - the monitor hardcoded BirdNET v2.4's 3-second clip length and overlap settings, producing false overrun warnings for Perch v2 (5-second clips with 695ms inference, well within its 2.5-second window). Now uses each model's actual buffer interval (#3085).
Thread Safety & Resource Leaks
- Labels race during model reload -
NumSpecies()andLabels()could read label data concurrently withloadLabels()mutations during model reload. Added mutex protection and defensive copy (#3100). - Settings clone missing Models.Installed - the
Installedslice was shared between cloned and original settings, allowing concurrent modifications to corrupt active config (#3100). - SSE progress handler leak on rapid install/reinstall - model install and reinstall handlers now clean up the previous SSE subscription before reassigning, preventing connection leaks (#3100).
- RebuildRangeFilter missing read lock - added read lock for consistency with all other range filter endpoints (#3100).
- SaveYAMLConfig file descriptor leak - added deferred close for panic-safe cleanup. On Windows, the leaked descriptor prevented temp file removal (#3100).
Configuration
- Season date comparison ignoring actual dates -
isDefaultSeasonConfigurationonly checked season names, silently overwriting user-customized start dates with system defaults. Now compares both names and dates (#3100).
Internationalization
- 491 untranslated keys translated - translated English fallback values to native translations across all 13 non-English locales, reducing untranslated instances from 1,205 to 714 (remaining are technical terms, brand names, and universal abbreviations) (#3096).
🛡️ VirusTotal Results: