spatialaudio / python-sounddevice

:sound: Play and Record Sound with Python :snake:
https://python-sounddevice.readthedocs.io/
MIT License
980 stars 145 forks source link

Won't be able to import sounddevice due to unknown issue with `libportaudio64bit.dll` #517

Open HaujetZhao opened 5 months ago

HaujetZhao commented 5 months ago

Today I met a Win10 22H2 computer which can not import sounddevice (0.4.6) neither with Python3.8 nor Python3.10.

It's when the code run to _check(_lib.Pa_Initialize(), 'Error initializing PortAudio') that the python interpreter froze, just froze still.

I realized it's maybe the dll problem, but I have no ability to debug more.

So I replaced the libportaudio64bit.dll with sherpa-onnx-portaudio.zip which came from another module (portaudio compiled using Vusual Studio Build Tool) and the problem solved.

I think I should let you know that.

mgeier commented 5 months ago

Thanks for reporting this!

Can you please try the DLL from https://github.com/spatialaudio/portaudio-binaries/actions/runs/7588358747?pr=14?

That one is built with Visual Studio via Github Actions. If that works, I can change the build process for the DLL.

HaujetZhao commented 5 months ago

Waiting for the ower's response. (of that special computer)

Works on mine.

I'll let you know once received response.

HaujetZhao commented 5 months ago

Update.

That user told me at first the new DLL worked, after minutes, he tried the initial (not workable) once (which still don't work), then the new DLL also won't work now. I confirmed that by remoting.

The sherpa-onnx-portaudio.zip (built with Visual Studio Build Tool 2022 on Windows 10 22H2) still works.

That's really weird. Is there anything I can help or a method to catch log?

HaujetZhao commented 5 months ago

I'm not familiar with the cmake process. But maybe this will help.

The sherpa-onnx-portaudio.zip I got is from this-repo , following it's doc:

git clone https://github.com/k2-fsa/sherpa-onnx
cd sherpa-onnx
python3 setup.py install

and in the build directory, the new portaudio DLL can be found.

It used the pa_stable_v190700_20210406.tgz to build, instead of the portaudio github repo.

Here is it's cmake file of portaudio:

function(download_portaudio)
  include(FetchContent)

  set(portaudio_URL  "https://files.portaudio.com/archives/pa_stable_v190700_20210406.tgz")
  set(portaudio_URL2 "https://huggingface.co/csukuangfj/sherpa-onnx-cmake-deps/resolve/main/pa_stable_v190700_20210406.tgz")
  set(portaudio_HASH "SHA256=47efbf42c77c19a05d22e627d42873e991ec0c1357219c0d74ce6a2948cb2def")

  # If you don't have access to the Internet, please download it to your
  # local drive and modify the following line according to your needs.
  set(possible_file_locations
    $ENV{HOME}/Downloads/pa_stable_v190700_20210406.tgz
    $ENV{HOME}/asr/pa_stable_v190700_20210406.tgz
    ${PROJECT_SOURCE_DIR}/pa_stable_v190700_20210406.tgz
    ${PROJECT_BINARY_DIR}/pa_stable_v190700_20210406.tgz
    /tmp/pa_stable_v190700_20210406.tgz
    /star-fj/fangjun/download/github/pa_stable_v190700_20210406.tgz
  )

  foreach(f IN LISTS possible_file_locations)
    if(EXISTS ${f})
      set(portaudio_URL  "${f}")
      file(TO_CMAKE_PATH "${portaudio_URL}" portaudio_URL)
      message(STATUS "Found local downloaded portaudio: ${portaudio_URL}")
      set(portaudio_URL2)
      break()
    endif()
  endforeach()

  if(BUILD_SHARED_LIBS)
    set(PA_BUILD_SHARED ON CACHE BOOL "" FORCE)
    set(PA_BUILD_STATIC OFF CACHE BOOL "" FORCE)
  else()
    set(PA_BUILD_SHARED OFF CACHE BOOL "" FORCE)
    set(PA_BUILD_STATIC ON CACHE BOOL "" FORCE)
  endif()

  FetchContent_Declare(portaudio
    URL
      ${portaudio_URL}
      ${portaudio_URL2}
    URL_HASH          ${portaudio_HASH}
  )

  FetchContent_GetProperties(portaudio)
  if(NOT portaudio_POPULATED)
    message(STATUS "Downloading portaudio from ${portaudio_URL}")
    FetchContent_Populate(portaudio)
  endif()
  message(STATUS "portaudio is downloaded to ${portaudio_SOURCE_DIR}")
  message(STATUS "portaudio's binary dir is ${portaudio_BINARY_DIR}")

  if(APPLE)
    set(CMAKE_MACOSX_RPATH ON) # to solve the following warning on macOS
  endif()

  add_subdirectory(${portaudio_SOURCE_DIR} ${portaudio_BINARY_DIR} EXCLUDE_FROM_ALL)

  if(BUILD_SHARED_LIBS)
    set_target_properties(portaudio PROPERTIES OUTPUT_NAME "sherpa-onnx-portaudio")
    if(NOT WIN32)
      target_compile_options(portaudio PRIVATE "-Wno-deprecated-declarations")
    endif()

    if(SHERPA_ONNX_ENABLE_PYTHON AND WIN32)
      install(TARGETS portaudio DESTINATION ..)
    else()
      install(TARGETS portaudio DESTINATION lib)
    endif()
  else()
    set_target_properties(portaudio_static PROPERTIES OUTPUT_NAME "sherpa-onnx-portaudio_static")
    if(NOT WIN32)
      target_compile_options(portaudio_static PRIVATE "-Wno-deprecated-declarations")
    endif()
    if(SHERPA_ONNX_ENABLE_PYTHON AND WIN32)
      install(TARGETS portaudio_static DESTINATION ..)
    else()
      install(TARGETS portaudio_static DESTINATION lib)
    endif()
  endif()
endfunction()

download_portaudio()

# Note
# See http://portaudio.com/docs/v19-doxydocs/tutorial_start.html
# for how to use portaudio
mgeier commented 5 months ago

Thanks for testing this again!

That user told me at first the new DLL worked, after minutes, he tried the initial (not workable) once (which still don't work), then the new DLL also won't work now. I confirmed that by remoting.

That's really weird.

That is indeed weird. But if the error only occurs after the old DLL is loaded, I don't think it's a problem, because this should not be loaded in the future anyway.

As long as the new DLL works that's great!

Is there anything I can help or a method to catch log?

Yes, you could help with 2 things: