Closes #11620: Fix support for SND_MEMORY in winsound.PlaySound.
Based on a patch by Tim Lesher.
This commit is contained in:
parent
0e76e67246
commit
ae8298bfb7
|
@ -25,7 +25,8 @@ provided by Windows platforms. It includes functions and several constants.
|
|||
.. function:: PlaySound(sound, flags)
|
||||
|
||||
Call the underlying :c:func:`PlaySound` function from the Platform API. The
|
||||
*sound* parameter may be a filename, audio data as a string, or ``None``. Its
|
||||
*sound* parameter may be a filename, a system sound alias, audio data as a
|
||||
:term:`bytes-like object`, or ``None``. Its
|
||||
interpretation depends on the value of *flags*, which can be a bitwise ORed
|
||||
combination of the constants described below. If the *sound* parameter is
|
||||
``None``, any currently playing waveform sound is stopped. If the system
|
||||
|
@ -92,7 +93,7 @@ provided by Windows platforms. It includes functions and several constants.
|
|||
.. data:: SND_MEMORY
|
||||
|
||||
The *sound* parameter to :func:`PlaySound` is a memory image of a WAV file, as a
|
||||
string.
|
||||
:term:`bytes-like object`.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -87,6 +87,22 @@ class PlaySoundTest(unittest.TestCase):
|
|||
winsound.PlaySound,
|
||||
"none", winsound.SND_ASYNC | winsound.SND_MEMORY
|
||||
)
|
||||
self.assertRaises(TypeError, winsound.PlaySound, b"bad", 0)
|
||||
self.assertRaises(TypeError, winsound.PlaySound, "bad",
|
||||
winsound.SND_MEMORY)
|
||||
self.assertRaises(TypeError, winsound.PlaySound, 1, 0)
|
||||
|
||||
def test_snd_memory(self):
|
||||
with open(support.findfile('pluck-pcm8.wav',
|
||||
subdir='audiodata'), 'rb') as f:
|
||||
audio_data = f.read()
|
||||
safe_PlaySound(audio_data, winsound.SND_MEMORY)
|
||||
audio_data = bytearray(audio_data)
|
||||
safe_PlaySound(audio_data, winsound.SND_MEMORY)
|
||||
|
||||
def test_snd_filename(self):
|
||||
fn = support.findfile('pluck-pcm8.wav', subdir='audiodata')
|
||||
safe_PlaySound(fn, winsound.SND_FILENAME | winsound.SND_NODEFAULT)
|
||||
|
||||
def test_aliases(self):
|
||||
aliases = [
|
||||
|
|
|
@ -75,6 +75,9 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #11620: Fix support for SND_MEMORY in winsound.PlaySound. Based on a
|
||||
patch by Tim Lesher.
|
||||
|
||||
- Issue #11734: Add support for IEEE 754 half-precision floats to the
|
||||
struct module. Based on a patch by Eli Stevens.
|
||||
|
||||
|
|
|
@ -17,16 +17,16 @@ PyDoc_STRVAR(winsound_PlaySound__doc__,
|
|||
{"PlaySound", (PyCFunction)winsound_PlaySound, METH_VARARGS, winsound_PlaySound__doc__},
|
||||
|
||||
static PyObject *
|
||||
winsound_PlaySound_impl(PyObject *module, Py_UNICODE *sound, int flags);
|
||||
winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags);
|
||||
|
||||
static PyObject *
|
||||
winsound_PlaySound(PyObject *module, PyObject *args)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
Py_UNICODE *sound;
|
||||
PyObject *sound;
|
||||
int flags;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "Zi:PlaySound",
|
||||
if (!PyArg_ParseTuple(args, "Oi:PlaySound",
|
||||
&sound, &flags)) {
|
||||
goto exit;
|
||||
}
|
||||
|
@ -100,4 +100,4 @@ winsound_MessageBeep(PyObject *module, PyObject *args)
|
|||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=1044b2adf3c67014 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=b999334e2e444ad2 input=a9049054013a1b77]*/
|
||||
|
|
|
@ -64,7 +64,7 @@ module winsound
|
|||
/*[clinic input]
|
||||
winsound.PlaySound
|
||||
|
||||
sound: Py_UNICODE(accept={str, NoneType})
|
||||
sound: object
|
||||
The sound to play; a filename, data, or None.
|
||||
flags: int
|
||||
Flag values, ored together. See module documentation.
|
||||
|
@ -74,22 +74,49 @@ A wrapper around the Windows PlaySound API.
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
winsound_PlaySound_impl(PyObject *module, Py_UNICODE *sound, int flags)
|
||||
/*[clinic end generated code: output=ec24b3a2b4368378 input=3411b1b7c1f36d93]*/
|
||||
winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags)
|
||||
/*[clinic end generated code: output=49a0fd16a372ebeb input=7bdf637f10201d37]*/
|
||||
{
|
||||
int ok;
|
||||
wchar_t *wsound;
|
||||
Py_buffer view = {NULL, NULL};
|
||||
|
||||
if (flags & SND_ASYNC && flags & SND_MEMORY) {
|
||||
/* Sidestep reference counting headache; unfortunately this also
|
||||
prevent SND_LOOP from memory. */
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Cannot play asynchronously from memory");
|
||||
return NULL;
|
||||
if (sound == Py_None) {
|
||||
wsound = NULL;
|
||||
} else if (flags & SND_MEMORY) {
|
||||
if (flags & SND_ASYNC) {
|
||||
/* Sidestep reference counting headache; unfortunately this also
|
||||
prevent SND_LOOP from memory. */
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Cannot play asynchronously from memory");
|
||||
return NULL;
|
||||
}
|
||||
if (PyObject_GetBuffer(sound, &view, PyBUF_SIMPLE) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
wsound = (wchar_t *)view.buf;
|
||||
} else {
|
||||
if (!PyUnicode_Check(sound)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"'sound' must be str or None, not '%s'",
|
||||
Py_TYPE(sound)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
wsound = PyUnicode_AsWideCharString(sound, NULL);
|
||||
if (wsound == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
ok = PlaySoundW(sound, NULL, flags);
|
||||
ok = PlaySoundW(wsound, NULL, flags);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (view.obj) {
|
||||
PyBuffer_Release(&view);
|
||||
} else if (sound != Py_None) {
|
||||
PyMem_Free(wsound);
|
||||
}
|
||||
if (!ok) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Failed to play sound");
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue