(filename)
| 49 | winsound.PlaySound(filename, winsound.SND_FILENAME) |
| 50 | |
| 51 | def _linux_wav_play(filename): |
| 52 | for _ in ("paplay", "aplay", "mpv", "mplayer", "play"): |
| 53 | if not os.system("%s '%s' 2>/dev/null" % (_, filename)): |
| 54 | return |
| 55 | |
| 56 | import ctypes |
| 57 | |
| 58 | PA_STREAM_PLAYBACK = 1 |
| 59 | PA_SAMPLE_S16LE = 3 |
| 60 | BUFFSIZE = 1024 |
| 61 | |
| 62 | class struct_pa_sample_spec(ctypes.Structure): |
| 63 | _fields_ = [("format", ctypes.c_int), ("rate", ctypes.c_uint32), ("channels", ctypes.c_uint8)] |
| 64 | |
| 65 | try: |
| 66 | pa = ctypes.cdll.LoadLibrary("libpulse-simple.so.0") |
| 67 | except OSError: |
| 68 | return |
| 69 | |
| 70 | wave_file = wave.open(filename, "rb") |
| 71 | |
| 72 | pa_sample_spec = struct_pa_sample_spec() |
| 73 | pa_sample_spec.rate = wave_file.getframerate() |
| 74 | pa_sample_spec.channels = wave_file.getnchannels() |
| 75 | pa_sample_spec.format = PA_SAMPLE_S16LE |
| 76 | |
| 77 | error = ctypes.c_int(0) |
| 78 | |
| 79 | pa_stream = pa.pa_simple_new(None, filename, PA_STREAM_PLAYBACK, None, "playback", ctypes.byref(pa_sample_spec), None, None, ctypes.byref(error)) |
| 80 | if not pa_stream: |
| 81 | raise Exception("Could not create pulse audio stream: %s" % pa.strerror(ctypes.byref(error))) |
| 82 | |
| 83 | while True: |
| 84 | latency = pa.pa_simple_get_latency(pa_stream, ctypes.byref(error)) |
| 85 | if latency == -1: |
| 86 | raise Exception("Getting latency failed") |
| 87 | |
| 88 | buf = wave_file.readframes(BUFFSIZE) |
| 89 | if not buf: |
| 90 | break |
| 91 | |
| 92 | if pa.pa_simple_write(pa_stream, buf, len(buf), ctypes.byref(error)): |
| 93 | raise Exception("Could not play file") |
| 94 | |
| 95 | wave_file.close() |
| 96 | |
| 97 | if pa.pa_simple_drain(pa_stream, ctypes.byref(error)): |
| 98 | raise Exception("Could not simple drain") |
| 99 | |
| 100 | pa.pa_simple_free(pa_stream) |
| 101 | |
| 102 | if __name__ == "__main__": |
| 103 | beep() |
no test coverage detected
searching dependent graphs…