Fix architecture detection on Windows ARM64#631
Conversation
When running an AMD64 Python on a Windows ARM64 host, platform.machine()
returns the host architecture instead of the process architecture, causing
sounddevice to try and load the wrong DLL.
>>> import sounddevice
Traceback (most recent call last):
File "C:\Users\bagpuss\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\sounddevice.py", line 72, in <module>
raise OSError('PortAudio library not found')
OSError: PortAudio library not found
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<python-input-1>", line 1, in <module>
import sounddevice
File "C:\Users\bagpuss\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\sounddevice.py", line 91, in <module>
_lib: ... = _ffi.dlopen(_libname)
~~~~~~~~~~~^^^^^^^^^^
OSError: cannot load library 'C:\Users\bagpuss\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\_sounddevice_data\portaudio-binaries\libportaudioarm64.dll': error 0x7e
The PROCESSOR_ARCHITECTURE environment variable can be used to get
process architecture. As far as I know, it should always be enough to
only check that variable but I wasn't feeling brave enough to not leave
the old detection as a fallback.
|
Thanks for this PR! Is there a way to check in CI that this previously failed? We currently have a test here: python-sounddevice/.github/workflows/sounddevice-data.yml Lines 17 to 18 in 2634256 It would be great to add a failing test and then fix it. BTW, see also bastibe/python-soundfile#460 for related discussions. |
It might always be defined, but it might also have additional values? It seems to be hard to find reliable information on what is guaranteed to be defined on which systems. It might be best to check only for the one you are interested in (AMD64) and leave all the rest to the fallback (until somebody else complains). |
57e8793 to
376db56
Compare
Looks like setup-python handles AMD64 on ARM64 well. Here's the error going the other way. Presumably the platform detection in Incidentally, you might want to switch that step to bash or use separate steps since powershell ignores the exit code for all but the last command. i.e. If all but the last check failed, it would be considered a pass.
That is pretty much the same code in the end. All I'd get rid of is the $ py -3-arm64 -c 'import os; print(os.environ["PROCESSOR_ARCHITECTURE"])'
ARM64
$ py -3 -c 'import os; print(os.environ["PROCESSOR_ARCHITECTURE"])'
AMD64
$ py -3-32 -c 'import os; print(os.environ["PROCESSOR_ARCHITECTURE"])'
x86 |
When running an AMD64 Python on a Windows ARM64 host, platform.machine() returns the host architecture instead of the process architecture, causing sounddevice to try and load the wrong DLL.
The PROCESSOR_ARCHITECTURE environment variable can be used to get process architecture. As far as I know, it should always be enough to only check that variable but I wasn't feeling brave enough to not leave the old detection as a fallback.