Skip to content

cffi library 'libsndfile.dll' has no function, constant or global variable named 'sf_wchar_open' #465

Open

Description

@alpinedelight

Firstly, wanted to start with saying thanks @bastibe for all your work and dedication

I'm trying to run soundfile on Windows on ARM64, I get the following error when calling sf.read function:
Error processing input: cffi library 'libsndfile.dll' has no function, constant or global variable named 'sf_wchar_open'.
Looking at dumpbin.exe /exports I can see libsndfile.dll (ARM64) contains sf_wchar_open, and creating a little test program I can call the function via cffi successfully.
I've tried reinstalling soundfile and cffi to no avail - I should mention pip install didn't deploy the DLL, and I had to place it manually.
Appreciate any help/thoughts.

import cffi
import os

ffi = cffi.FFI()

ffi.cdef("""
    typedef struct SNDFILE_tag SNDFILE;
    typedef struct SF_INFO {
        long long frames;
        int samplerate;
        int channels;
        int format;
        int sections;
        int seekable;
    } SF_INFO;
    
    SNDFILE* sf_wchar_open(const wchar_t* path, int mode, SF_INFO* sfinfo);
""")

def load_dll_and_test():
    try:
        dll_path = "libsndfile_arm64.dll"
        lib = ffi.dlopen(dll_path)
        print(f"Successfully loaded {dll_path}")
        
        sfinfo = ffi.new("SF_INFO *")
        
        file_path = "test.wav"  # Replace with actual file path
        
        wchar_path = ffi.new("wchar_t[]", file_path)
        
        sndfile = lib.sf_wchar_open(wchar_path, 0x10, sfinfo)
        
        if sndfile != ffi.NULL:
            print("Successfully opened audio file")
            print(f"Sample rate: {sfinfo.samplerate}")
            print(f"Channels: {sfinfo.channels}")
            print(f"Frames: {sfinfo.frames}")
        else:
            print("Failed to open audio file")
            
    except Exception as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    load_dll_and_test()

Platform/Version:
=== CFFI ===
Version: 1.17.1
=== SoundFile ===
Version: 0.13.1
=== Platform ===
Platform: Windows-11-10.0.26100-SP0
Architecture: ('64bit', 'WindowsPE')
Machine: ARM64
Processor: ARMv8 (64-bit) Family 8 Model 1 Revision 201, Qualcomm Technologies Inc
Python version: 3.13.5

Activity

  1. bastibe commented on Jul 28, 2025

    @bastibe
    Owner

    I have an arm64 version of libsndfile ready to be deployed. However, I'm still waiting for numpy and cffi to deploy their arm64 wheels. As far as I can tell, numpy has released a preview for Python 3.14, and CFFI is working on it.

    But until they are published and available, we can't release soundfile.

  2. alpinedelight commented on Jul 28, 2025

    @alpinedelight
    Author

    cgohlke has kindly compiled wheels here for CFFI & numpy: Windows on Arm Python Libraries.
    Can we test against those in the interim? I was able call CFFI and use the libsndfile you have provided.
    Thanks again.

  3. bastibe commented on Jul 28, 2025

    @bastibe
    Owner
  4. alpinedelight commented on Jul 28, 2025

    @alpinedelight
    Author

    yessir

  5. bastibe commented on Jul 29, 2025

    @bastibe
    Owner

    Last time I tried, sysconfig.get_platform() reported arm64 on Windows regardless of whether you're running an x64 or arm64 binary on an arm processor. This made it impossible to determine the correct binary.

    See, e.g. #463 for reference.

  6. alpinedelight commented on Jul 29, 2025

    @alpinedelight
    Author

    You're right - mad.
    Not elegant, but in lieu of any official function, one could attempt to load both, i.e.

        process_architecture = None;
        lib = None;
        
        try:
            print("Attempting to load libsndfile for x64 architecture")
            dll_path = "libsndfile_x64.dll" #"libsndfile_arm64.dll"
            lib = ffi.dlopen(dll_path)
            print(f"Successfully loaded {dll_path}")
            process_architecture = "x64"
        except Exception as e:
            print(f"Failed to load x64. Error: {e}")
        
        try:
            print("Attempting to load libsndfile for ARM64 architecture")
            dll_path = "libsndfile_arm64.dll" #"libsndfile_arm64.dll"
            lib = ffi.dlopen(dll_path)
            print(f"Successfully loaded {dll_path}")
            process_architecture = "ARM64"
        except Exception as e:
            print(f"Failed to load ARM64. Error: {e}")
    
        print(f"{bcolors.OKCYAN}Loaded libsndfile for architecture: {process_architecture} {bcolors.ENDC}")
    
    Image
  7. bastibe commented on Aug 5, 2025

    @bastibe
    Owner

    That's actually an acceptable workaround. Thank you.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions