Skip to content

Fix architecture detection on Windows ARM64#631

Open
bwoodsend wants to merge 2 commits into
spatialaudio:masterfrom
bwoodsend:windows-x64-on-arm64
Open

Fix architecture detection on Windows ARM64#631
bwoodsend wants to merge 2 commits into
spatialaudio:masterfrom
bwoodsend:windows-x64-on-arm64

Conversation

@bwoodsend
Copy link
Copy Markdown

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.

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.
@mgeier
Copy link
Copy Markdown
Member

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:

- os: windows-11-arm
arch: 'arm64'

It would be great to add a failing test and then fix it.

BTW, see also bastibe/python-soundfile#460 for related discussions.

@mgeier
Copy link
Copy Markdown
Member

mgeier commented May 14, 2026

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.

It might always be defined, but it might also have additional values?
Could it be wow64?

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).

@bwoodsend bwoodsend force-pushed the windows-x64-on-arm64 branch from 57e8793 to 376db56 Compare May 14, 2026 20:09
@bwoodsend
Copy link
Copy Markdown
Author

Is there a way to check in CI that this previously failed? We currently have a test here:

Looks like setup-python handles AMD64 on ARM64 well.

Here's the error going the other way. Presumably the platform detection in setup.py needs the same treatment...

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.

It might always be defined, but it might also have additional values?
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).

That is pretty much the same code in the end. All I'd get rid of is the ARM64 key in that dict since it gets that one right anyway. With the current change, an unrecognised PROCESSOR_ARCHITECTURE value should lead to the fallback path as before.

$ 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants