hamiltron / py-simple-audio

A simple audio playback Python extension - cross-platform, asynchronous, dependency-free
Other
159 stars 36 forks source link

Hard crash after sound finishes playing with python 3.12 #72

Open scottnm opened 9 months ago

scottnm commented 9 months ago

overview

simpleaudio 1.0.4 seems to crash for me when using python 3.12

the same crash does not reproduce in python 3.11

the crash does not appear to be any form of python failure that I can either catch as an exception or intercept with a python debugger

example

Here's the sample code I'm testing with

try:
    wav_file = simpleaudio.WaveObject.from_wave_file('test.wav')
    print('playing sound(s) using simpleaudio')
    play_obj = wav_file.play()
    play_obj.wait_done()
    print('done')
    play_obj.stop()
    print('stopped')
except BaseException as ex:
    print(f"caught exception {ex}")

when run from a python 3.12 environment with simpleaudio 1.0.4, this is the output

> python .\main.py
playing sound(s) using simpleaudio

here's the same run but from a python 3.11 environment

> python .\main.py
playing sound(s) using simpleaudio
done
stopped

Repro Environment information

scottnm commented 9 months ago

for additional context, I found another user on reddit who seemed to be experiencing a similar problem (although their repro was via pydub) https://www.reddit.com/r/pythonhelp/comments/17vw5zy/python_is_hard_crashing_with_a_simple_mp3_play/

though if I understand correctly, pydub uses simpleaudio for playback

cexen commented 9 months ago

The cause of the segmentation fault seems to be calling PyMem_Free(*) without acquiring the GIL.

There are two solutions (both of which solved the problem for me). :

  1. Replace all PyMem_Malloc(*) with PyMem_RawMalloc(*) and PyMem_Free(*) with PyMem_RawFree(*).
  2. Sandwich all PyMem_Free(*) between PyGILState_STATE gstate = PyGILState_Ensure(); and PyGILState_Release(gstate);.

The former solution is probably better.

With the above changes and rebuild I am able to use simpleaudio in Py3.12. https://github.com/cexen/py-simple-audio

pip install -U --force git+https://github.com/cexen/py-simple-audio.git

I am not familiar enough with package development (especially CI and backward compatibility) to know how to make the necessary changes for users in all environments...

Spacexplorer11 commented 7 months ago

@cexen Thanks a lot! I got the same issue and this fixed it!

Triangle4 commented 3 months ago

Yeah this bug renders simpleaudio unusable.