Uh oh!
There was an error while loading. Please reload this page.
Fix architecture detection on Windows ARM64 - #631
Conversation
mgeier
commented
May 14, 2026
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. |
mgeier
commented
May 14, 2026
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
376db56Comparebwoodsend
commented
May 14, 2026
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 |
bwoodsend
commented
May 19, 2026
That should be CI happy and everything that #460 was trying to do done. |
mgeier
commented
May 23, 2026
Thanks for the updates!
That's what I'd like to understand ... so you could get rid of I would like to know which code is there because we need it and which code is there for no particular reason. I'm not doubting that it works, but I would like to optimize the code for human understanding and future maintenance. |
bwoodsend
commented
May 25, 2026
You can because there's not such thing as running an ARM64 process on AMD64 or x86. How about just... - if _platform.machine().lower() in ('arm64', 'aarch64'):+ if _platform.machine().lower() in ('arm64', 'aarch64') and _os.environ.get("PROCESSOR_ARCHITECTURE", "") not in ("x86", "AMD64"):
_platform_suffix = 'arm64'
else:
_platform_suffix = _platform.architecture()[0]...? |
mgeier
commented
Jun 6, 2026
Yes, I think this would be better. I've also just seen bastibe/python-soundfile#489 which provides a nice overview table and suggests using |
Hmm, when I did this yonks ago, I was put off Now it's defined based on compile time target detection (albeit with a fallback to sys.platform). It is also what pip uses (via I'm pretty certain all 3 options will work so I'm good with whichever one sounds the least icky to you... |
mgeier
commented
Jun 14, 2026
Thanks for the additional information. Everything related to Windows sounds icky to me! But I think it would be good to avoid relying on environment variables if that's at all feasible (and it now seems to be). |
bwoodsend
commented
Jun 19, 2026
How about... diff --git i/src/sounddevice.py w/src/sounddevice.py
index 00fc6f8..ad38411 100644
--- i/src/sounddevice.py+++ w/src/sounddevice.py@@ -55,6 +55,7 @@ import contextlib as _contextlib
import os as _os
import platform as _platform
import sys as _sys
+import sysconfig as _sysconfig
from ctypes.util import find_library as _find_library
from _sounddevice import ffi as _ffi
@@ -75,7 +76,7 @@ except OSError:
if _platform.system() == 'Darwin':
_libname = 'libportaudio.dylib'
elif _platform.system() == 'Windows':
- if _platform.machine().lower() in ('arm64', 'aarch64'):+ if 'arm64' in _sysconfig.get_platform() or 'aarch64' in _sysconfig.get_platform():
_platform_suffix = 'arm64'
else:
_platform_suffix = _platform.architecture()[0]... then? The |
mgeier
commented
Jul 12, 2026
Sorry for the late response ... this looks very good to me, nice and simple! If we can support MINGW/MSYS2, that's great! |
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
Switch to sysconfig.get_platform() which does the right thing under
emulation.92e7a0d to
1418197CompareUh oh!
There was an error while loading. Please reload this page.
mgeier
commented
Jul 24, 2026
Thanks for following through with this! |
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.