Open ArnoXf opened 5 years ago
How did you install soundfile? My first guess would be that you did not install the wheel version (which comes with a full-featured libsndfile), but used some other installation method instead that does not come with its own libsndfile, thus using your system's libsndfile, which is lacking FLAC support.
I am getting the same error. I did a conda install librosa, which took care of libsndfile dependencies But I'm using libsndfile v1.0.28 (in the current conda environment), which is supposed to support FLAC. @bastibe how do I correct this?
I'm working in a conda environment with:
The problem in your case is probably that you're using pysoundfile
, instead of soundfile
. We deprecated the use of py
soundfile a while ago, and the version is no longer maintained.
That was a problem, but I uninstalled pysoundfile, and now installed soundfile (v0.10.3). But I'm getting the same error: "RuntimeError: Error opening '/Users/.../audio/hains006.flac': File contains data in an unimplemented format. Also, when I do soundfile.available_formats(), FLAC doesn't appear.
You'll have to check which version of libsndfile is actually used by soundfile. It might still be using the one from conda, which would explain why the newer version of soundfile (which comes with a fully-configured libsndfile) didn't fix the problem.
Since you seem to be on macOS, you can also try installing libsndfile through homebrew. If I remember correctly, homebrew has options for enabling FLAC support.
If all else fails, you can use LD_PRELOAD
to force loading a specific version of libsndfile and see if that fixes the issue. And then work backwards from there to figure out why soundfile is not loading the version you prefer.
@MR-T77 You can try this to find out which libsndfile is used on your system:
import soundfile as sf
print(sf._libname)
Thanks for your help @bastibe and @mgeier. Unfortunately, I'm a little bit lost on what to do next...
Yesterday I had installed libsndfile through homebrew, but that didn't fix. (I tried also brew install libsndfile --with-flac
but got "Error: invalid option: --with-flac" - on Macos Mojave - 10.14)
If I do print print(sf._libname)
I get "/.../anaconda/envs/dynamite/bin/../lib/libsndfile.dylib" but I don't know how to interpret this info.
Any other path I may explore before LD_PRELOAD
, which seems to require a higher level of expertise than the one I have.
I get "/.../anaconda/envs/dynamite/bin/../lib/libsndfile.dylib" but I don't know how to interpret this info.
This tells you from which file on your system the libsndfile
library is loaded.
The path you are getting points somewhere inside your Anaconda folder. It's not the one distributed with the soundfile
wheel package.
There seem to be FLAC problems with the macOS version of the Anaconda package, see https://github.com/conda-forge/libsndfile-feedstock/issues/2 and https://github.com/librosa/librosa/pull/847#issuecomment-475044902. There doesn't seem to be a resolution.
You should try to uninstall libsndfile
with conda
, then it probably works.
I just stumbled across this very issue, but the source of the conflicting libsndfile.dylib
was from homebrew. libsndfile
is a dependency of ffmpeg
, portaudio
, sox
and other packages commonly distributed via the brew
package manager on macOS.
Unfortunately, soundfile
picks up the libsndfile.dylib
file that homebrew distrubutes
$ python
Python 3.7.7 (default, Jun 19 2020, 13:21:43)
[Clang 11.0.3 (clang-1103.0.32.62)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import soundfile as sf
>>> sf._libname
'/usr/local/lib/libsndfile.dylib'
>>> import ctypes
>>> ctypes.util.find_library("sndfile")
'/usr/local/lib/libsndfile.dylib'
After uninstalling libsndfile
from homebrew via brew uninstall --ignore-dependencies libsndfile
soundfile works as expected
$ python
Python 3.7.7 (default, Jun 19 2020, 13:21:43)
[Clang 11.0.3 (clang-1103.0.32.62)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import soundfile as sf
>>> sf._libname
'libsndfile.dylib'
Unfortunately, tools like ffmpeg, sox, etc I use routinely, so removing the homebrew bundled dependency for it is rather problematic. Would there be a workaround to specify which libsndfile.dylib
file should be used?
You could probably LD_PRELOAD it. (I think that works on macOS, right?)
AFAIK LD_PRELOAD does not work on macOS/OSX, but I'm operating out of my depth here. After re-installing libsndfile via homebrew:
For the record, this is the location of my libsndfile.dylib
library provided by soundfile: /Users/ogi/.zinit/plugins/pyenv---pyenv/versions/3.7.7/envs/fred/lib/python3.7/site-packages/_soundfile_data/libsndfile.dylib
$ python
Python 3.7.7 (default, Jun 19 2020, 13:21:43)
[Clang 11.0.3 (clang-1103.0.32.62)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import soundfile as sf
>>> sf._libname
'/usr/local/lib/libsndfile.dylib'
>>> exit()
$ DYLD_INSERT_LIBRARIES="/Users/ogi/.zinit/plugins/pyenv---pyenv/versions/3.7.7/envs/fred/lib/python3.7/site-packages/_soundfile_data/libsndfile.dylib" python
Python 3.7.7 (default, Jun 19 2020, 13:21:43)
[Clang 11.0.3 (clang-1103.0.32.62)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import soundfile as sf
>>> sf._libname
'/usr/local/lib/libsndfile.dylib'
>>> exit()
$ LD_PRELOAD="/Users/ogi/.zinit/plugins/pyenv---pyenv/versions/3.7.7/envs/fred/lib/python3.7/site-packages/_soundfile_data/libsndfile.dylib" python
Python 3.7.7 (default, Jun 19 2020, 13:21:43)
[Clang 11.0.3 (clang-1103.0.32.62)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import soundfile as sf
>>> sf._libname
'/usr/local/lib/libsndfile.dylib'
>>>
Looking through the documentation for ctypes.util.find_library()
I found this blurb
If wrapping a shared library with ctypes, it may be better to determine the shared library name at development time, and hardcode that into the wrapper module instead of using find_library() to locate the library at runtime.
If wrapping a shared library with ctypes, it may be better to determine the shared library name at development time, and hardcode that into the wrapper module instead of using find_library() to locate the library at runtime.
The soundfile
module actually does that, but only on the second attempt.
First, it tries to find the library with ctypes.util.find_library()
. If that fails, it tries the hard-coded path in _soundfile_data
.
The problem here is that the first attempt does not fail ...
As a work-around, you can monkey-patch the find_library()
function to make it fail unconditionally:
def dummy_find_library(name):
return None
import ctypes.util
ctypes.util.find_library = dummy_find_library
import soundfile as sf
...
Another idea: Why not just overwrite /usr/local/lib/libsndfile.dylib
?
I assume this is a symbolic link provided by brew
, right?
You could just copy the libsndfile.dylib
from the soundfile
module there, and hope that all other programs like ffmpeg
, portaudio
, sox
continue working.
First, it tries to find the library with
ctypes.util.find_library()
. If that fails, it tries the hard-coded path in_soundfile_data
.
After I posted my reply, I noticed that too! I don't have enough experience doing this sort of thing to make a recommendation on how it should be done so I leave that to the judgment of more experienced folks. I am curious though if it would be worthwhile to try loading the hard-coded path first and then fall back on find_library()
?
Another idea: Why not just overwrite
/usr/local/lib/libsndfile.dylib
?
I think this is what I'll end up doing for the time being. I must admit I am curious why their version of libsndfile does not support flac files, but that's not a topic for this issue tracker.
Thanks for your input @mgeier !
If there would be consideration for implementing the change where first soundfile attempts to read the hard-coded paths before falling back on find_library()
I'll gladly submit one.
I don't think there is a "right" or "wrong" order in which to look for the library, each one has their advantages and disadvantages.
The original idea was to give users a simple way to override the pre-packaged library with their own.
As usual in Linux (and this works in macOS as well), they could put their version of the library into /usr/local/lib/libsndfile.so
, and it would be preferred over the one installed by the package manager (which is typically in /usr/lib/libsndfile.so
or something like that).
That's exactly what happened in your case, @j9ac9k. If someone puts a library into /usr/local/lib
, they normally want it to be used, don't they? So I would say that's a feature, not a bug.
Now if we reverse the order of library loading, this wouldn't be possible anymore, people would not (easily) be able to provide their own library version. This might actually be an advantage for some users, but I think in general it's not.
If we disable the current customization opportunity, I think we should introduce a new one, do you have an idea for that?
I wanted to mention a related discussion in https://github.com/spatialaudio/python-sounddevice/issues/130, but then I saw that you have also commented there!
UPDATE: another related issue: #222.
I'm getting this issue on ubuntu as well.
I'm getting this issue on ubuntu as well.
I didn't come up w/ a good fix; in my case I just uninstalled the libsndfile that was packaged via homebrew. I do periodically think about this issue; I suspect an environment variable may be the way to go here; I'm not sure how difficult that would be to implement though.
I suspect an environment variable may be the way to go here; I'm not sure how difficult that would be to implement though.
This would be relatively easy to implement. Pull requests would certainly be welcome!
I'm getting the same issue on ubuntu 20: 04
When I uninstall libsndfile, it uninstalled librosa as well and when I install just soundfile and libsndfile. sf.read("text.flac"); works fine, but when I noticed librosa was uninstalled, I installed it again and since librosa takes care of libsnfile dependencies, it installed a different version and sf.read("text.flac") stopped working.
any ideas why this is so?
Find a work around with the issue hope it might help out, still to try @mgeier solution with the def dummy_find_library() function,
but what I did was I uninstall librosa and it uninstalled all it dependent packages :$ conda uninstall librosa -y
and I install soundfile and loaded the .flac file and it works. but when I install librosa again installed libsnfile and soundfile._libname by default picks and **"/.../anaconda/*/libsndfile.so.1" found in anaconda.
I uninstall just that package :$ conda remove --force libndfile
soundfile._libname default to "libsnfile.so.1", which works alongside librosa.
Hoping to get a far more better and accurate solution in the future.
Hallefrickenluja! @VegasC you rescued me from 5 hours of package hell.
conda remove --force libndfile worked for me!
Hi!
I got an issue when trying to open a FLAC file using the following simple code:
That results in the following traceback:
The available formats don't show FLAC:
but the subformats with format flac does:
Also FLAC is in the supported formats in both soundfile.py and sndfile.h
Also, FLAC files can be played in macOS.
Does anyone know how to resolve that issue?
Thanks in advance