diff --git a/birdnet-pi/DOCS.md b/birdnet-pi/DOCS.md index 65cfe7aa2..fa1d0898b 100644 --- a/birdnet-pi/DOCS.md +++ b/birdnet-pi/DOCS.md @@ -1,55 +1,60 @@ # Microphone considerations -The critical element is the microphone quality : a Boya By-lm 40 or clippy EM272 (with a very good aux-usb converter) is key to improve the quality of detections. -Here is some example tests I did (whole threads are really interesting also): https://github.com/mcguirepr89/BirdNET-Pi/discussions/39#discussioncomment-9706951 -https://github.com/mcguirepr89/BirdNET-Pi/discussions/1092#discussioncomment-9706191 -My recommendation : -- Best entry system (< 50€) : Boya By-lm40 (30€) + deadcat (10 €) -- Best middle end system (< 150 €) : Clippy EM272 TRS/TRRS (55€) + Rode AI micro trs/trrs to usb (70€) + Rycote deadcat (27€) -- Best high end system (<400 €) : Clippy EM272 XLR (85€) or LOM Ucho Pro (75€) + Focusrite Scarlet 2i2 4th Gen (200€) + Bubblebee Pro Extreme deadcat (45€) +The critical element is the microphone quality: a Boya By-lm 40 or Clippy EM272 (with a very good aux-usb converter) is key to improve the quality of detections. -Sources for high end microphones in Europe: -- Clippy (EM272) : https://www.veldshop.nl/en/clippy-xlr-em272z1-mono-microphone.html -- LOM (EM272) : https://store.lom.audio/collections/basicucho-series -- Immersive sound (AOM5024) : https://immersivesoundscapes.com/earsight-standard-v2/ +Here are some example tests I did (the whole threads are really interesting also): + +- +- + +**My recommendation:** + +- **Best entry system (< 50 €):** Boya By-lm40 (30 €) + deadcat (10 €) +- **Best middle end system (< 150 €):** Clippy EM272 TRS/TRRS (55 €) + Rode AI micro trs/trrs to usb (70 €) + Rycote deadcat (27 €) +- **Best high end system (<400 €):** Clippy EM272 XLR (85 €) or LOM Ucho Pro (75 €) + Focusrite Scarlet 2i2 4th Gen (200 €) + Bubblebee Pro Extreme deadcat (45 €) + +**Sources for high end microphones in Europe:** + +- Clippy (EM272): +- LOM (EM272): +- Immersive sound (AOM5024): # App settings recommendation -I've tested lots of settings by running 2 versions of my HA birdnet-pi addon in parallel using the same rtsp feed, and comparing impact of parameters. -My conclusions aren't universal, as it seems to be highly dependent on the region and type of mic used. For example, the old model seems to be better in Australia, while the new one better in Europe. -- Model - - Version : 6k_v2,4 _(performs better in Europe at least, the 6k performs better in Australia)_ - - Species range model : v1 _(uncheck v2.4 ; seems more robust in Europe)_ - - Species occurence threshold : 0,001 _(was 0,00015 using v2.4 ; use the Species List Tester to check the correct value for you)_ -- Audio settings - - Default - - Channel : 1 _(doesn't really matter as analysis is made on mono signal ; 1 allows decreased saved audio size but seems to give slightly messed up spectrograms in my experience)_ - - Recording Length : 18 _(that's because I use an overlap of 0,5 ; so it analysis 0-3s ; 2,5-5,5s ; 5-8s ; 7,5-10,5 ; 10-13 ; 12,5-15,5 ; 15-18)_ - - Extraction Length : 9s _(could be 6, but I like to hear my birds :-))_ - - Audio format : mp3 _(why bother with something else)_ -- Birdnet-lite settings - - Overlap : 0,5s - - Minimum confidence : 0,7 - - Sigmoid sensitivity : 1,25 _(I've tried 1,00 but it gave much more false positives ; as decreasing this value increases sensitivity)_ +I've tested lots of settings by running 2 versions of my HA birdnet-pi addon in parallel using the same RTSP feed and comparing the impact of parameters. My conclusions aren't universal, as it seems to be highly dependent on the region and type of mic used. For example, the old model seems to be better in Australia, while the new one is better in Europe. + +- **Model** + - **Version:** 6k_v2.4 _(performs better in Europe at least, the 6k performs better in Australia)_ + - **Species range model:** v1 _(uncheck v2.4; seems more robust in Europe)_ + - **Species occurrence threshold:** 0.001 _(was 0.00015 using v2.4; use the Species List Tester to check the correct value for you)_ +- **Audio settings** + - **Default** + - **Channel:** 1 _(doesn't really matter as analysis is made on mono signal; 1 allows decreased saved audio size but seems to give slightly messed up spectrograms in my experience)_ + - **Recording Length:** 18 _(that's because I use an overlap of 0.5; so it analyzes 0-3s, 2.5-5.5s, 5-8s, 7.5-10.5, 10-13, 12.5-15.5, 15-18)_ + - **Extraction Length:** 9s _(could be 6, but I like to hear my birds :-))_ + - **Audio format:** mp3 _(why bother with something else)_ +- **Birdnet-lite settings** + - **Overlap:** 0.5s + - **Minimum confidence:** 0.7 + - **Sigmoid sensitivity:** 1.25 _(I've tried 1.00 but it gave much more false positives; decreasing this value increases sensitivity)_ # Set RTSP server -Inspired by : https://github.com/mcguirepr89/BirdNET-Pi/discussions/1006#discussioncomment-6747450 +Inspired by:
On your desktop - + - Download imager - Install raspbian lite 64 +
With ssh, install requisite softwares -### -``` +```bash # Update - sudo apt-get update -y sudo apt-get dist-upgrade -y @@ -57,25 +62,30 @@ sudo apt-get dist-upgrade -y sudo apt-get install -y micro ffmpeg lsof sudo -s cd /root && wget -c https://github.com/bluenviron/mediamtx/releases/download/v1.9.1/mediamtx_v1.9.1_linux_arm64v8.tar.gz -O - | sudo tar -xz ``` -
-
Configure Audio ### Find right device -``` + +```bash # List audio devices arecord -l -# Check audio device parameters. Example : +# Check audio device parameters. Example: arecord -D hw:1,0 --dump-hw-params ``` ### Add startup script + +```bash sudo nano startmic.sh && chmod +x startmic.sh ``` + +Paste the following content: + +```bash #!/bin/bash echo "Starting birdmic" @@ -91,13 +101,11 @@ if [ -z "$SCARLETT_INDEX" ]; then fi # Start mediamtx first and give it a moment to initialize -./mediamtx & +./mediamtx & sleep 5 - + # Run ffmpeg -ffmpeg -nostdin -use_wallclock_as_timestamps 1 -fflags +genpts -f alsa -acodec pcm_s16be -ac 2 -ar 96000 \ --i plughw:$SCARLETT_INDEX,0 -ac 2 -f rtsp -acodec pcm_s16be rtsp://localhost:8554/birdmic -rtsp_transport tcp \ --buffer_size 512k 2>/tmp/rtsp_error & +ffmpeg -nostdin -use_wallclock_as_timestamps 1 -fflags +genpts -f alsa -acodec pcm_s16be -ac 2 -ar 96000 -i plughw:$SCARLETT_INDEX,0 -ac 2 -f rtsp -acodec pcm_s16be rtsp://localhost:8554/birdmic -rtsp_transport tcp -buffer_size 512k 2>/tmp/rtsp_error & # Set microphone volume sleep 5 @@ -115,13 +123,12 @@ if [ -f "$HOME/autogain.py" ]; then sudo python3 -u "$HOME/autogain.py" >/tmp/log_autogain 2>/tmp/log_autogain_error & fi ``` -
-Optional : use gstreamer instead of ffmpeg +Optional: use gstreamer instead of ffmpeg -``` +```bash # Install gstreamer sudo apt-get update #sudo apt-get install -y \ @@ -136,8 +143,9 @@ sudo apt-get update apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio -y ``` -Create a script named rtsp_audio_server.py -``` +Create a script named `rtsp_audio_server.py`: + +```python #!/usr/bin/env python3 import gi @@ -167,22 +175,19 @@ logger = logging.getLogger(__name__) class AudioFactory(GstRtspServer.RTSPMediaFactory): def __init__(self): super(AudioFactory, self).__init__() - self.set_shared(True) # Allow multiple clients to access the stream - self.set_latency(500) # Increase latency to 500ms to improve stream stability - self.set_suspend_mode(GstRtspServer.RTSPSuspendMode.NONE) # Prevent suspension of the stream when no clients are connected + self.set_shared(True) + self.set_latency(500) + self.set_suspend_mode(GstRtspServer.RTSPSuspendMode.NONE) logger.debug("AudioFactory initialized: shared=True, latency=500ms, suspend_mode=NONE.") def do_create_element(self, url): - """ - Create and return the GStreamer pipeline for streaming audio. - """ pipeline_str = ( - "alsasrc device=plughw:0,0 do-timestamp=true buffer-time=2000000 latency-time=1000000 ! " # Increased buffer size - "queue max-size-buffers=0 max-size-bytes=0 max-size-time=0 ! " # Add queue to handle buffer management - "audioconvert ! " # Convert audio to a suitable format - "audioresample ! " # Resample audio if necessary - "audio/x-raw,format=S16BE,channels=2,rate=48000 ! " # Set audio properties (rate = 48kHz) - "rtpL16pay name=pay0 pt=96" # Payload for RTP + "alsasrc device=plughw:0,0 do-timestamp=true buffer-time=2000000 latency-time=1000000 ! " + "queue max-size-buffers=0 max-size-bytes=0 max-size-time=0 ! " + "audioconvert ! " + "audioresample ! " + "audio/x-raw,format=S16BE,channels=2,rate=48000 ! " + "rtpL16pay name=pay0 pt=96" ) logger.debug(f"Creating GStreamer pipeline: {pipeline_str}") try: @@ -198,34 +203,30 @@ class AudioFactory(GstRtspServer.RTSPMediaFactory): class GstServer: def __init__(self): self.server = GstRtspServer.RTSPServer() - self.server.set_service("8554") # Set the RTSP server port - self.server.set_address("0.0.0.0") # Listen on all network interfaces + self.server.set_service("8554") + self.server.set_address("0.0.0.0") logger.debug("RTSP server configured: address=0.0.0.0, port=8554.") factory = AudioFactory() mount_points = self.server.get_mount_points() - mount_points.add_factory("/birdmic", factory) # Mount point + mount_points.add_factory("/birdmic", factory) logger.debug("Factory mounted at /birdmic.") - self.server.attach(None) # Attach the server to the default main context + self.server.attach(None) logger.info("RTSP server attached and running.") def main(): - # Create GstServer instance server = GstServer() print("RTSP server is running at rtsp://localhost:8554/birdmic") logger.info("RTSP server is running at rtsp://localhost:8554/birdmic") - # Set up the main loop with proper logging loop = GLib.MainLoop() - # Handle termination signals to ensure graceful shutdown def shutdown(signum, frame): logger.info(f"Shutting down RTSP server due to signal {signum}.") print("\nShutting down RTSP server.") loop.quit() - # Register signal handlers for graceful termination signal.signal(signal.SIGINT, shutdown) signal.signal(signal.SIGTERM, shutdown) @@ -237,34 +238,43 @@ def main(): logger.info("RTSP server has been shut down.") if __name__ == "__main__": - # Ensure log file exists if not os.path.exists(LOG_FILE): open(LOG_FILE, 'w').close() main() ``` -
-Optional : Startup automatically +Optional: Startup automatically -``` +```bash chmod +x startmic.sh crontab -e # select nano as your editor ``` -Paste in `@reboot $HOME/startmic.sh` then save and exit nano. +Paste in: + +```bash +@reboot $HOME/startmic.sh +``` + +then save and exit nano. Reboot the Pi and test again with VLC to make sure the RTSP stream is live.
-Optional : disable unecessary elements +Optional: disable unnecessary elements -- Optimize config.txt +- **Optimize config.txt** +```bash sudo nano /boot/firmware/config.txt ``` + +Paste in: + +```ini # Enable audio and USB optimizations dtparam=audio=off # Disable the default onboard audio to prevent conflicts dtoverlay=disable-bt # Disable onboard Bluetooth to reduce USB bandwidth usage @@ -280,10 +290,9 @@ avoid_pwm_pll=1 # Use a more stable PLL for the audio clock hdmi_blanking=1 # Disable HDMI (save power and reduce interference) ``` -- Disable useless services - -``` +- **Disable useless services** +```bash # Disable useless services sudo systemctl disable hciuart sudo systemctl disable bluetooth @@ -320,15 +329,13 @@ sudo apt install -y cpufrequtils echo 'GOVERNOR="performance"' | sudo tee /etc/default/cpufrequtils sudo systemctl disable ondemand sudo systemctl stop ondemand - ``` -
-Optional : install Focusrite driver - -``` +Optional: install Focusrite driver + +```bash sudo apt-get install make linux-headers-$(uname -r) curl -LO https://github.com/geoffreybennett/scarlett-gen2/releases/download/v6.9-v1.3/snd-usb-audio-kmod-6.6-v1.3.tar.gz tar -xzf snd-usb-audio-kmod-6.6-v1.3.tar.gz @@ -341,32 +348,40 @@ sudo depmod sudo reboot dmesg | grep -A 5 -B 5 -i focusrite ``` -
-Optional : add RAM disk - -``` +Optional: add RAM disk + +```bash sudo cp /usr/share/systemd/tmp.mount /etc/systemd/system/tmp.mount sudo systemctl enable tmp.mount sudo systemctl start tmp.mount ``` +
+ +
+Optional: Configuration for Focusrite Scarlett 2i2 + +Add this content in `$HOME/focusrite.sh` and run: + +```bash +chmod +x "$HOME/focusrite.sh" +``` + +See:
-Optional : Configuration for Focusrite Scarlett 2i2 +Optional: Autogain script for microphone -Add this content in "$HOME/focusrite.sh" && chmod +x "$HOME/focusrite.sh" -https://github.com/alexbelgium/Birdnet-tools/blob/main/focusrite.sh - -
- -
-Optional : Autogain script for microphone - -Add this content in "$HOME/autogain.py" && chmod +x "$HOME/autogain.py" -See : https://github.com/alexbelgium/Birdnet-tools/blob/main/autogain.py +Add this content in `$HOME/autogain.py` and run: + +```bash +chmod +x "$HOME/autogain.py" +``` + +See: