Nachtzuster / BirdNET-Pi

A realtime acoustic bird classification system for the Raspberry Pi 5, 4B 3B+ 0W2 and more. Built on the TFLite version of BirdNET.
https://birdnetpi.com
Other
172 stars 24 forks source link

ModuleNotFoundError: No module named 'resampy' #212

Closed unosonic closed 1 month ago

unosonic commented 1 month ago

Describe the bug A fresh install (tested on rpi4, rpi zero2) exits successfully, everything seems fine, microphone is working, but analyzing seems to fail. Log is showing the following error:

23:52:14---[birdnet_analysis][INFO] Analyzing BirdSongs/StreamData/2024-10-02-birdnet-23:51:58.wav
23:52:14---[server][INFO] READING AUDIO DATA...
23:52:14---[birdnet_analysis][ERROR] Unexpected error:
23:52:14---Traceback (most recent call last):
23:52:14---  File "/usr/local/bin/birdnet_analysis.py", line 91, in process_file
23:52:14---    detections = run_analysis(file)
23:52:14---                 ^^^^^^^^^^^^^^^^^^
23:52:14---  File "BirdNET-Pi/scripts/server.py", line 321, in run_analysis
23:52:14---    audio_data = readAudioData(file.file_name, conf.getfloat('OVERLAP'))
23:52:14---                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23:52:14---  File "BirdNET-Pi/scripts/server.py", line 181, in readAudioData
23:52:14---    sig, rate = librosa.load(path, sr=sample_rate, mono=True, res_type='kaiser_fast')
23:52:14---                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23:52:14---  File "BirdNET-Pi/birdnet/lib/python3.11/site-packages/librosa/core/audio.py", line 193, in load
23:52:14---    y = resample(y, orig_sr=sr_native, target_sr=sr, res_type=res_type)
23:52:14---        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23:52:14---  File "BirdNET-Pi/birdnet/lib/python3.11/site-packages/librosa/core/audio.py", line 678, in resample
23:52:14---    y_hat = resampy.resample(y, orig_sr, target_sr, filter=res_type, axis=axis)
23:52:14---            ^^^^^^^^^^^^^^^^
23:52:14---  File "BirdNET-Pi/birdnet/lib/python3.11/site-packages/lazy_loader/__init__.py", line 117, in __getattr__
23:52:14---    raise ModuleNotFoundError(
23:52:14---ModuleNotFoundError: No module named 'resampy'
23:52:14---This error is lazily reported, having originally occured in
23:52:14---  File BirdNET-Pi/birdnet/lib/python3.11/site-packages/librosa/core/audio.py, line 33, in <module>
23:52:14-------> resampy = lazy.load("resampy")

To Reproduce

Expected behavior successful analysis of recorded audio file

Your build

Operating System: Debian GNU/Linux 12 (bookworm)
Kernel: Linux 6.6.51+rpt-rpi-v8 Architecture: arm64 8GB RAM

Code or log snippets see above

unosonic commented 1 month ago

I was able to fix the problem locally by installing resampy manually into the birdnet virtual environment, but since it showed the same error ModuleNotFoundError: No module named 'resampy' on at least 5 fresh installations, it looks like a bug to me rather than a local issue.

birdy2:~/BirdNET-Pi$ source birdnet/bin/activate
(birdnet) birdy2:~/BirdNET-Pi$ pip install resampy
...
Installing collected packages: resampy
Successfully installed resampy-0.4.3
...

(birdnet) birdy2:~/BirdNET-Pi$ python -c "import resampy; print(resampy.__version__)"
0.4.3
(birdnet) birdy2:~/BirdNET-Pi$ deactivate
Nachtzuster commented 1 month ago

Hmmm, I can't reproduce the issue. resampy isn't installed on any of my installs, which is fine, it is only needed when the audio is recorded at a sampling rate other that 48k... but the audio recording is hard-coded to be at 48k.

I'm wondering how it is able to hit that code path.

unosonic commented 1 month ago

Interesting. For reason of parallel access to the microphone (eg. by other apps) I'm using a special shared PCM device defined in /etc/asound.conf which is set to 44.1kHz sample rate. asound.conf code attached. So that audio device can only deliver at 44.1kHz and then needs resampling.

pcm.mobilemic {
    type dsnoop
    ipc_key 1024
    ipc_key_add_uid false   # let multiple users share
    ipc_perm 0666           # IPC permissions for multi-user sharing (octal, default 0600)
    slave {
        pcm "hw:IQaudIOCODEC"   # the actual device
        channels 2
        rate 44100
        period_size 1024
        buffer_size 4096
    }
}
unosonic commented 1 month ago

I admit that such a specific PCM device is rather uncommon.. ;) maybe it'd be better to include resampy for such rare cases, since it does the job well and is referenced in your code anyway.