blob: d45584868650678938db272736ee3f25b4183df2 [file] [log] [blame]
Guido van Rossume6005781999-02-04 22:40:42 +00001/* Author: Toby Dickenson <htrd90@zepler.org>
2 *
3 * Copyright (c) 1999 Toby Dickenson
4 *
5 * Permission to use this software in any way is granted without
6 * fee, provided that the copyright notice above appears in all
7 * copies. This software is provided "as is" without any warranty.
8 */
9
10/* Modified by Guido van Rossum */
Guido van Rossum99eb7a11999-10-01 14:29:17 +000011/* Beep added by Mark Hammond */
Tim Peters25a9ce32001-02-19 07:06:36 +000012/* Win9X Beep and platform identification added by Uncle Timmy */
Guido van Rossume6005781999-02-04 22:40:42 +000013
14/* Example:
15
16 import winsound
17 import time
18
Tim Peters25a9ce32001-02-19 07:06:36 +000019 # Play wav file
Guido van Rossume6005781999-02-04 22:40:42 +000020 winsound.PlaySound('c:/windows/media/Chord.wav', winsound.SND_FILENAME)
21
22 # Play sound from control panel settings
23 winsound.PlaySound('SystemQuestion', winsound.SND_ALIAS)
24
25 # Play wav file from memory
26 data=open('c:/windows/media/Chimes.wav',"rb").read()
27 winsound.PlaySound(data, winsound.SND_MEMORY)
28
29 # Start playing the first bit of wav file asynchronously
30 winsound.PlaySound('c:/windows/media/Chord.wav',
31 winsound.SND_FILENAME|winsound.SND_ASYNC)
32 # But dont let it go for too long...
33 time.sleep(0.1)
34 # ...Before stopping it
35 winsound.PlaySound(None, 0)
36*/
37
Guido van Rossume7ba4952007-06-06 23:52:48 +000038#include <Python.h>
Guido van Rossume6005781999-02-04 22:40:42 +000039#include <windows.h>
40#include <mmsystem.h>
Guido van Rossume6005781999-02-04 22:40:42 +000041
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000042PyDoc_STRVAR(sound_playsound_doc,
Guido van Rossume6005781999-02-04 22:40:42 +000043"PlaySound(sound, flags) - a wrapper around the Windows PlaySound API\n"
44"\n"
45"The sound argument can be a filename, data, or None.\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000046"For flag values, ored together, see module documentation.");
Guido van Rossume6005781999-02-04 22:40:42 +000047
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048PyDoc_STRVAR(sound_beep_doc,
Guido van Rossum99eb7a11999-10-01 14:29:17 +000049"Beep(frequency, duration) - a wrapper around the Windows Beep API\n"
50"\n"
51"The frequency argument specifies frequency, in hertz, of the sound.\n"
Tim Peters25a9ce32001-02-19 07:06:36 +000052"This parameter must be in the range 37 through 32,767.\n"
Alexandre Vassalottieca20b62008-05-16 02:54:33 +000053"The duration argument specifies the number of milliseconds.\n");
Guido van Rossum99eb7a11999-10-01 14:29:17 +000054
Guido van Rossume1252682003-04-09 19:38:08 +000055PyDoc_STRVAR(sound_msgbeep_doc,
56"MessageBeep(x) - call Windows MessageBeep(x). x defaults to MB_OK.");
57
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000058PyDoc_STRVAR(sound_module_doc,
Guido van Rossume6005781999-02-04 22:40:42 +000059"PlaySound(sound, flags) - play a sound\n"
60"SND_FILENAME - sound is a wav file name\n"
Tim Peterse79af272001-02-20 10:02:21 +000061"SND_ALIAS - sound is a registry sound association name\n"
Guido van Rossume6005781999-02-04 22:40:42 +000062"SND_LOOP - Play the sound repeatedly; must also specify SND_ASYNC\n"
63"SND_MEMORY - sound is a memory image of a wav file\n"
64"SND_PURGE - stop all instances of the specified sound\n"
65"SND_ASYNC - PlaySound returns immediately\n"
66"SND_NODEFAULT - Do not play a default beep if the sound can not be found\n"
67"SND_NOSTOP - Do not interrupt any sounds currently playing\n" // Raising RuntimeError if needed
68"SND_NOWAIT - Return immediately if the sound driver is busy\n" // Without any errors
Guido van Rossum99eb7a11999-10-01 14:29:17 +000069"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000070"Beep(frequency, duration) - Make a beep through the PC speaker.");
Guido van Rossume6005781999-02-04 22:40:42 +000071
Walter Dörwaldfee100402003-05-22 17:22:54 +000072static PyObject *
Tim Peters25a9ce32001-02-19 07:06:36 +000073sound_playsound(PyObject *s, PyObject *args)
Guido van Rossume6005781999-02-04 22:40:42 +000074{
Hirokazu Yamamoto339293a2010-11-07 11:53:57 +000075 Py_UNICODE *wsound;
76 PyObject *osound;
Guido van Rossume6005781999-02-04 22:40:42 +000077 const char *sound;
78 int flags;
Guido van Rossume6005781999-02-04 22:40:42 +000079 int ok;
80
Hirokazu Yamamoto339293a2010-11-07 11:53:57 +000081 if (PyArg_ParseTuple(args, "Zi:PlaySound", &wsound, &flags)) {
82 if (flags & SND_ASYNC && flags & SND_MEMORY) {
83 /* Sidestep reference counting headache; unfortunately this also
84 prevent SND_LOOP from memory. */
85 PyErr_SetString(PyExc_RuntimeError, "Cannot play asynchronously from memory");
86 return NULL;
87 }
88 Py_BEGIN_ALLOW_THREADS
89 ok = PlaySoundW(wsound, NULL, flags);
90 Py_END_ALLOW_THREADS
91 if (!ok) {
92 PyErr_SetString(PyExc_RuntimeError, "Failed to play sound");
93 return NULL;
94 }
95 Py_INCREF(Py_None);
96 return Py_None;
Guido van Rossume6005781999-02-04 22:40:42 +000097 }
Hirokazu Yamamoto339293a2010-11-07 11:53:57 +000098 /* Drop the argument parsing error as narrow strings
99 are also valid. */
100 PyErr_Clear();
101 if (!PyArg_ParseTuple(args, "O&i:PlaySound",
102 PyUnicode_FSConverter, &osound, &flags))
103 return NULL;
Hirokazu Yamamotoc6610152010-11-07 11:41:07 +0000104 if (flags & SND_ASYNC && flags & SND_MEMORY) {
105 /* Sidestep reference counting headache; unfortunately this also
106 prevent SND_LOOP from memory. */
107 PyErr_SetString(PyExc_RuntimeError, "Cannot play asynchronously from memory");
Hirokazu Yamamoto339293a2010-11-07 11:53:57 +0000108 Py_DECREF(osound);
Hirokazu Yamamotoc6610152010-11-07 11:41:07 +0000109 return NULL;
Guido van Rossume6005781999-02-04 22:40:42 +0000110 }
Hirokazu Yamamoto339293a2010-11-07 11:53:57 +0000111 sound = PyBytes_AsString(osound);
Guido van Rossume6005781999-02-04 22:40:42 +0000112 Py_BEGIN_ALLOW_THREADS
Hirokazu Yamamoto339293a2010-11-07 11:53:57 +0000113 ok = PlaySoundA(sound, NULL, flags);
Guido van Rossume6005781999-02-04 22:40:42 +0000114 Py_END_ALLOW_THREADS
Hirokazu Yamamotoc6610152010-11-07 11:41:07 +0000115 if (!ok) {
116 PyErr_SetString(PyExc_RuntimeError, "Failed to play sound");
Hirokazu Yamamoto339293a2010-11-07 11:53:57 +0000117 Py_DECREF(osound);
Hirokazu Yamamotoc6610152010-11-07 11:41:07 +0000118 return NULL;
Guido van Rossume6005781999-02-04 22:40:42 +0000119 }
Hirokazu Yamamoto339293a2010-11-07 11:53:57 +0000120 Py_DECREF(osound);
Guido van Rossume6005781999-02-04 22:40:42 +0000121 Py_INCREF(Py_None);
122 return Py_None;
123}
124
Tim Peters25a9ce32001-02-19 07:06:36 +0000125static PyObject *
126sound_beep(PyObject *self, PyObject *args)
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000127{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000128 int freq;
129 int dur;
130 BOOL ok;
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000131
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000132 if (!PyArg_ParseTuple(args, "ii:Beep", &freq, &dur))
133 return NULL;
Tim Peters25a9ce32001-02-19 07:06:36 +0000134
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000135 if (freq < 37 || freq > 32767) {
136 PyErr_SetString(PyExc_ValueError,
137 "frequency must be in 37 thru 32767");
138 return NULL;
139 }
Tim Peters25a9ce32001-02-19 07:06:36 +0000140
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000141 Py_BEGIN_ALLOW_THREADS
142 ok = Beep(freq, dur);
143 Py_END_ALLOW_THREADS
144 if (!ok) {
145 PyErr_SetString(PyExc_RuntimeError,"Failed to beep");
146 return NULL;
147 }
Tim Peters25a9ce32001-02-19 07:06:36 +0000148
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000149 Py_INCREF(Py_None);
150 return Py_None;
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000151}
152
Guido van Rossume1252682003-04-09 19:38:08 +0000153static PyObject *
154sound_msgbeep(PyObject *self, PyObject *args)
155{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000156 int x = MB_OK;
157 if (!PyArg_ParseTuple(args, "|i:MessageBeep", &x))
158 return NULL;
159 MessageBeep(x);
160 Py_INCREF(Py_None);
161 return Py_None;
Guido van Rossume1252682003-04-09 19:38:08 +0000162}
163
Guido van Rossume6005781999-02-04 22:40:42 +0000164static struct PyMethodDef sound_methods[] =
165{
Neal Norwitz031829d2002-03-31 14:37:44 +0000166 {"PlaySound", sound_playsound, METH_VARARGS, sound_playsound_doc},
167 {"Beep", sound_beep, METH_VARARGS, sound_beep_doc},
Guido van Rossume1252682003-04-09 19:38:08 +0000168 {"MessageBeep", sound_msgbeep, METH_VARARGS, sound_msgbeep_doc},
Guido van Rossume6005781999-02-04 22:40:42 +0000169 {NULL, NULL}
170};
171
Tim Peters25a9ce32001-02-19 07:06:36 +0000172static void
173add_define(PyObject *dict, const char *key, long value)
Guido van Rossume6005781999-02-04 22:40:42 +0000174{
Hirokazu Yamamotoc6610152010-11-07 11:41:07 +0000175 PyObject *k = PyUnicode_FromString(key);
176 PyObject *v = PyLong_FromLong(value);
177 if (v && k) {
178 PyDict_SetItem(dict, k, v);
Guido van Rossume6005781999-02-04 22:40:42 +0000179 }
180 Py_XDECREF(k);
181 Py_XDECREF(v);
182}
183
184#define ADD_DEFINE(tok) add_define(dict,#tok,tok)
185
Martin v. Löwis1a214512008-06-11 05:26:20 +0000186
187static struct PyModuleDef winsoundmodule = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000188 PyModuleDef_HEAD_INIT,
189 "winsound",
190 sound_module_doc,
191 -1,
192 sound_methods,
193 NULL,
194 NULL,
195 NULL,
196 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000197};
198
Mark Hammonde407e2a2002-07-22 13:26:41 +0000199PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000200PyInit_winsound(void)
Guido van Rossume6005781999-02-04 22:40:42 +0000201{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000202 PyObject *dict;
203 PyObject *module = PyModule_Create(&winsoundmodule);
204 if (module == NULL)
205 return NULL;
206 dict = PyModule_GetDict(module);
Tim Peters25a9ce32001-02-19 07:06:36 +0000207
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000208 ADD_DEFINE(SND_ASYNC);
209 ADD_DEFINE(SND_NODEFAULT);
210 ADD_DEFINE(SND_NOSTOP);
211 ADD_DEFINE(SND_NOWAIT);
212 ADD_DEFINE(SND_ALIAS);
213 ADD_DEFINE(SND_FILENAME);
214 ADD_DEFINE(SND_MEMORY);
215 ADD_DEFINE(SND_PURGE);
216 ADD_DEFINE(SND_LOOP);
217 ADD_DEFINE(SND_APPLICATION);
Tim Peters25a9ce32001-02-19 07:06:36 +0000218
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000219 ADD_DEFINE(MB_OK);
220 ADD_DEFINE(MB_ICONASTERISK);
221 ADD_DEFINE(MB_ICONEXCLAMATION);
222 ADD_DEFINE(MB_ICONHAND);
223 ADD_DEFINE(MB_ICONQUESTION);
224 return module;
Guido van Rossume6005781999-02-04 22:40:42 +0000225}