python-soundfile icon indicating copy to clipboard operation
python-soundfile copied to clipboard

find_library is failed to get the sndfile

Open openedev opened this issue 5 years ago • 12 comments

This issues has observed while importing soundfile module at arm64 target. target runs on Python 3.7.4.

Soundfile.py is unable to get the sndfile but the same /usr/lib/libsndfile.so

linux$ python3 test_imports/test_audio.py Traceback (most recent call last): File "test_imports/test_audio.py", line 5, in import soundfile File "usr/lib/python3.7/site-packages/soundfile.py", line 142, in OSError: sndfile library not found

So, I tried ctype.CDLL instead of find_library -- _libname = _find_library('sndfile') ++ _libname = ctypes.CDLL('libsndfile.so') ++ print('Library: %s' % _libname)

But it is failing to open the _libname

linux$ python3 test_imports/test_audio.py Library: <CDLL 'libsndfile.so', handle 3a832320 at 0x7f97cf0b50> Traceback (most recent call last): File "test_imports/test_audio.py", line 5, in import soundfile File "usr/lib/python3.7/site-packages/soundfile.py", line 147, in TypeError: load_library() argument 1 must be str, bytes or bytearray, not CDLL

Any proper fix for this?

Jagan.

openedev avatar Feb 15 '20 12:02 openedev

Is libsndfile installed?

bastibe avatar Feb 17 '20 08:02 bastibe

@bastibe Yes, it is there in /usr/lib/libsndfile.so

openedev avatar Feb 17 '20 09:02 openedev

As you found out yourself, _find_library is ctypes.find_library, which is part of Python proper.

So you'll have to figure out why Python can't locate your /usr/lib/libsndfile.so. Perhaps it's missing from some runtime path or library search path, or perhaps Python was compiled with some missing definitions, or for an incompatible runtime or something like that.

You can probably LD_PRELOAD it manually if need be, but that's not fixing the underlying problem.

bastibe avatar Feb 17 '20 10:02 bastibe

@bastibe I have a buildroot environment, as per as compilation is concern I did a clean build to make sure nothing missed in-terms of dependencies.

I don't have any LD_LIBRARY_PATH on my shell env, since the systems is pretty much a rootfs rather than a distro.

openedev avatar Feb 17 '20 16:02 openedev

As a first step, try LD_PRELOADing libsndfile.so and see whether that fixes your issue. If that works, you know your libsndfile is compatible and works as intended. Then you can figure out why Python isn't finding it.

bastibe avatar Feb 18 '20 10:02 bastibe

@bastibe not sure I have used it properly, would you please check the below syntax and correct me If I'm wrong.

linux$ car test.py import soundfile linux$ LD_PRELOAD=/usr/lib/libsndfile.so python3 test.py Traceback (most recent call last): File "test.py", line 1, in import soundfile File "/usr/lib/python3.7/site-packages/soundfile.py", line 142, in raise OSError('sndfile library not found') OSError: sndfile library not found

linux$ LD_PRELOAD=/usr/lib/libsndfile.so python3 -c "import soundfile" Traceback (most recent call last): File "", line 1, in File "/usr/lib/python3.7/site-packages/soundfile.py", line 142, in raise OSError('sndfile library not found') OSError: sndfile library not found

openedev avatar Feb 18 '20 15:02 openedev

That looks correct.

I'd say that either your libsndfile is somehow incompatible with your Python (different compiler, different glibc, or something like that), or your Python installation is somehow misconfigured.

I'd recommend playing around with ctypes.find_library, and see if you can make it find your libsndfile somehow. Perhaps by passing the full path to it, or "libsndfile" instead of "sndfile". Perhaps by copying the libsndfile to a different location. Usually, it should pick up these differences on its own, but on a non-standard platform, you never know.

I've had to deal with issues like this in a different project. Perhaps the following function can help: https://github.com/bastibe/transplant/blob/master/transplant/transplant_master.py#L654

bastibe avatar Feb 18 '20 15:02 bastibe

I know it sound improper, but I can went through by explicitly mention the path like below. --- a/soundfile.py +++ b/soundfile.py @@ -13,7 +13,7 @@ version = "0.10.3" import os as _os import sys as _sys from os import SEEK_SET, SEEK_CUR, SEEK_END --from ctypes.util import find_library as _find_library ++from ctypes import cdll from _soundfile import ffi as _ffi

try: @@ -137,10 +137,10 @@ _ffi_types = { }

try: -- _libname = _find_library('sndfile') ++ _libname = cdll.LoadLibrary('libsndfile.so') if _libname is None: raise OSError('sndfile library not found') -- _snd = _ffi.dlopen(_libname) ++ _snd = _ffi.dlopen("/usr/lib/libsndfile.so") except OSError: if _sys.platform == 'darwin': _libname = 'libsndfile.dylib'

I tried to find the way to get the libsndfile.so in the system via some os.path.abspath or similar but none can give the desired path of libsndfile.so. @bastibe any clue on this might help to get through this work around atleast for now. thanks!

openedev avatar Feb 19 '20 09:02 openedev

Does the _ffi.dlopen('/usr/lib/libsndfile.so') work?

If so, you'll have to either

  • figure out what is misconfigured in your system that prevents ctypes.util.find_library from finding libraries in /usr/lib/, or
  • live with your workaround.

If not, the library is probably incompatible in some way and can't be loaded. Then you'll have to figure out how they differ, or how to get compatible versions of Python and the library.

bastibe avatar Feb 19 '20 10:02 bastibe

Weirdly yes! _ffi.dlopen('/usr/lib/libsndfile.so') seems to work in a buildroot embedded image with python 3.9 and libsndfile.

So, in a kind've wild turn of events, this appears to be a bug in python, that at least pyusb solved with a custom load override. I recently ran into this while making a Rhasspy satellite image in Buildroot, and started looking around. Apparently it's an issue with buildroot not having a library finding mechanism that python can use for find_library.

For now I'm planning on using a slightly modified soundfile.py. I know this is a really niche subset of folks using python-soundfile on embedded systems, so I'm just letting you know mostly for awareness (and for anyone else who comes across this) as testing something like this on a real system is not easy.

Thanks for the work on python-soundfile btw - it's used in a lot of places far and wide!

JarvyJ avatar Oct 22 '21 02:10 JarvyJ

Thank you!

If you'd like, I'd be grateful for an addition to the README, perhaps under the Known Issues header, to help other users who might be experiencing the same issue.

bastibe avatar Oct 22 '21 06:10 bastibe

Yeah, I can make that happen!

JarvyJ avatar Oct 25 '21 03:10 JarvyJ