Open ealpha opened 2 years ago
See #270.
I'm open to suggestions how to improve the situation.
I cloned the repo and hacked at it until it worked.
https://github.com/gormster/python-sounddevice/tree/api-mode-experimental
Note that this replaces ABI mode completely with API mode. I'm sure there's a graceful way to handle both.
also, I should probably be overriding build_py
not install
but I couldn't get that to work. I don't have a ton of experience with setuptools and the documentation is pretty spotty.
Thanks @gormster, see also #91.
Note that this replaces ABI mode completely with API mode. I'm sure there's a graceful way to handle both.
This would be great, but I'm not so sure that's possible.
See also https://groups.google.com/g/python-cffi/c/oBMFw7R1sFI/m/LJDo6NPJCwAJ
Ok so… I've done a thing where it does (I think) handle this gracefully. (Well, sort of; it uses an environment variable at runtime to select which mode to use. That was the best I could think of without breaking the API.) However, in testing it, I realised the original problem is actually only occurring when using a conda
environment and not in my base Python install.
So I tried using it under my conda
install and… well, it also seems to work when I build it from source. I'm kind of a novice with conda, I usually use pipenv, but it seems like (especially for M1 Macs) conda is a lot more usable.
And here's the kicker: if I go into a fresh conda environment with numpy installed, then within that environment do python -m pip install sounddevice
… that also works fine. Even though that should be identical to conda install
. I mean… python -m pip install
is literally exactly what conda install does according to the recipe for python-sounddevice
. And yet… it doesn't work the same. I don't get it.
In short: I have no real way of testing that this patch fixes this bug at all.
Now, this all said, API mode is clearly superior in cases where a C compiler is available, or for which a wheel can be precompiled, and it sure seems like the way I've done it does switch between API and ABI mode seamlessly… but again, it's tough to test if that's actually what's happening.
@ealpha In case you missed it in that wall of text, here's a potential workaround:
conda
environment. Do not install python-sounddevice
. (You can install numpy
or whatever else you want.)conda activate
to enter your new environmentpython -m pip install sounddevice
Not contributing to the actual issue, but if I install via conda conda install python-sounddevice
, I end up with the installation from conda-forge, not PyPI. This is due to my conda configuration also considering conda-forge.
Otherwise one would do conda install python-sounddevice -c conda-forge
. But in that case one ends up with all packages from conda-forge instead of conda-main. For things like numpy this is not preferable however (strong performance differences depending on system architecture).
So an okay way around that would be (resulting in a version of portaudio from conda-forge, but same version number as conda-main):
conda create -n sd numpy
conda activate sd
conda install python-sounddevice -c conda-forge
There are at least two versions of the PortAudio library availble for conda
:
It is theoretically possible to install portaudio
with conda
and sounddevice
with pip
, but I don't think that makes sense.
However, it is possible to not install portaudio
with conda
and then install sounddevice
with pip
, as @gormster mentioned above. In this case, the bundled PortAudio library from https://github.com/spatialaudio/portaudio-binaries will be used.
In any case, you can check which library is actually used like this:
import sounddevice as sd
print(sd._libname)
In general, I would recommend conda-forge
over the default channel. However, I wasn't aware of this:
For things like numpy this is not preferable however (strong performance differences depending on system architecture).
This seems unfortunate. Why is conda-forge
not as good? Isn't that something that should be fixed?
I didn't find an issue for that: https://github.com/conda-forge/numpy-feedstock/issues
https://anaconda.org/anaconda/numpy https://anaconda.org/conda-forge/numpy
In general, I would recommend
conda-forge
over the default channel. However, I wasn't aware of this:For things like numpy this is not preferable however (strong performance differences depending on system architecture).
This seems unfortunate. Why is
conda-forge
not as good? Isn't that something that should be fixed? I didn't find an issue for that: https://github.com/conda-forge/numpy-feedstock/issueshttps://anaconda.org/anaconda/numpy https://anaconda.org/conda-forge/numpy
FYI, the difference is what accelerated linear algebra library Numpy is built against, as documented here https://numpy.org/install/#numpy-packages--accelerated-linear-algebra-libraries. I suppose the conclusion of "strong performance differences" should be taken with a grain of salt and seen in context of what one is intending to do, and on what system architecture.
@ealpha In case you missed it in that wall of text, here's a potential workaround:
- Create a fresh
conda
environment. Do not installpython-sounddevice
. (You can installnumpy
or whatever else you want.)- Use
conda activate
to enter your new environment- Run
python -m pip install sounddevice
This worked for me. Just a heads up for other people, if you conda install other packages that has cffi as a dependency (after python -m pip install sounddevice
), it might muck things up. Better to use pip for those packages.
I still have this problem in macOS 12.6
@ealpha You may want to make sure that you install cffi via pip as well as stated by @AjaniStewart. I can confirm that the workaround works on macOS 12.6 & arm64 if cffi and sounddevice are installed using pip.
You can use python -m pip install sounddevice --force-reinstall
to do so, beware that this will do a force reinstall of all dependencies though.
Hi, I had the same issue with my M1 mac mini, macos 13.0 & anaconda environment.
pip uninstall cffi
pip install cffi
It works for me.
python3 play_file.py file.wav
MemoryError: Cannot allocate write+execute memory for ffi.callback(). You might be running on a system that prevents this. For more information, see https://cffi.readthedocs.io/en/latest/using.html#callbacks