blob: b564eaba780cd6b840a69fe47e063e8ef3778334 [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{
Victor Stinner9d3b93b2011-11-22 02:27:30 +010075 wchar_t *wsound;
Guido van Rossume6005781999-02-04 22:40:42 +000076 int flags;
Guido van Rossume6005781999-02-04 22:40:42 +000077 int ok;
78
Hirokazu Yamamotoc08c9bc2010-11-07 09:23:15 +000079 if (PyArg_ParseTuple(args, "Zi:PlaySound", &wsound, &flags)) {
80 if (flags & SND_ASYNC && flags & SND_MEMORY) {
81 /* Sidestep reference counting headache; unfortunately this also
82 prevent SND_LOOP from memory. */
83 PyErr_SetString(PyExc_RuntimeError, "Cannot play asynchronously from memory");
84 return NULL;
85 }
86 Py_BEGIN_ALLOW_THREADS
87 ok = PlaySoundW(wsound, NULL, flags);
88 Py_END_ALLOW_THREADS
89 if (!ok) {
90 PyErr_SetString(PyExc_RuntimeError, "Failed to play sound");
91 return NULL;
92 }
93 Py_INCREF(Py_None);
94 return Py_None;
Guido van Rossume6005781999-02-04 22:40:42 +000095 }
Hirokazu Yamamoto4ae5f132010-11-07 14:29:26 +000096 return NULL;
Guido van Rossume6005781999-02-04 22:40:42 +000097}
98
Tim Peters25a9ce32001-02-19 07:06:36 +000099static PyObject *
100sound_beep(PyObject *self, PyObject *args)
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 int freq;
103 int dur;
104 BOOL ok;
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 if (!PyArg_ParseTuple(args, "ii:Beep", &freq, &dur))
107 return NULL;
Tim Peters25a9ce32001-02-19 07:06:36 +0000108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 if (freq < 37 || freq > 32767) {
110 PyErr_SetString(PyExc_ValueError,
111 "frequency must be in 37 thru 32767");
112 return NULL;
113 }
Tim Peters25a9ce32001-02-19 07:06:36 +0000114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 Py_BEGIN_ALLOW_THREADS
116 ok = Beep(freq, dur);
117 Py_END_ALLOW_THREADS
118 if (!ok) {
119 PyErr_SetString(PyExc_RuntimeError,"Failed to beep");
120 return NULL;
121 }
Tim Peters25a9ce32001-02-19 07:06:36 +0000122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 Py_INCREF(Py_None);
124 return Py_None;
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000125}
126
Guido van Rossume1252682003-04-09 19:38:08 +0000127static PyObject *
128sound_msgbeep(PyObject *self, PyObject *args)
129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 int x = MB_OK;
131 if (!PyArg_ParseTuple(args, "|i:MessageBeep", &x))
132 return NULL;
133 MessageBeep(x);
134 Py_INCREF(Py_None);
135 return Py_None;
Guido van Rossume1252682003-04-09 19:38:08 +0000136}
137
Guido van Rossume6005781999-02-04 22:40:42 +0000138static struct PyMethodDef sound_methods[] =
139{
Neal Norwitz031829d2002-03-31 14:37:44 +0000140 {"PlaySound", sound_playsound, METH_VARARGS, sound_playsound_doc},
141 {"Beep", sound_beep, METH_VARARGS, sound_beep_doc},
Guido van Rossume1252682003-04-09 19:38:08 +0000142 {"MessageBeep", sound_msgbeep, METH_VARARGS, sound_msgbeep_doc},
Guido van Rossume6005781999-02-04 22:40:42 +0000143 {NULL, NULL}
144};
145
Tim Peters25a9ce32001-02-19 07:06:36 +0000146static void
147add_define(PyObject *dict, const char *key, long value)
Guido van Rossume6005781999-02-04 22:40:42 +0000148{
Hirokazu Yamamoto62fbdd92010-11-07 02:45:19 +0000149 PyObject *k = PyUnicode_FromString(key);
150 PyObject *v = PyLong_FromLong(value);
151 if (v && k) {
Hirokazu Yamamotocdc8cdd2010-11-07 11:07:44 +0000152 PyDict_SetItem(dict, k, v);
Guido van Rossume6005781999-02-04 22:40:42 +0000153 }
154 Py_XDECREF(k);
155 Py_XDECREF(v);
156}
157
158#define ADD_DEFINE(tok) add_define(dict,#tok,tok)
159
Martin v. Löwis1a214512008-06-11 05:26:20 +0000160
161static struct PyModuleDef winsoundmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 PyModuleDef_HEAD_INIT,
163 "winsound",
164 sound_module_doc,
165 -1,
166 sound_methods,
167 NULL,
168 NULL,
169 NULL,
170 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000171};
172
Mark Hammonde407e2a2002-07-22 13:26:41 +0000173PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000174PyInit_winsound(void)
Guido van Rossume6005781999-02-04 22:40:42 +0000175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 PyObject *dict;
177 PyObject *module = PyModule_Create(&winsoundmodule);
178 if (module == NULL)
179 return NULL;
180 dict = PyModule_GetDict(module);
Tim Peters25a9ce32001-02-19 07:06:36 +0000181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 ADD_DEFINE(SND_ASYNC);
183 ADD_DEFINE(SND_NODEFAULT);
184 ADD_DEFINE(SND_NOSTOP);
185 ADD_DEFINE(SND_NOWAIT);
186 ADD_DEFINE(SND_ALIAS);
187 ADD_DEFINE(SND_FILENAME);
188 ADD_DEFINE(SND_MEMORY);
189 ADD_DEFINE(SND_PURGE);
190 ADD_DEFINE(SND_LOOP);
191 ADD_DEFINE(SND_APPLICATION);
Tim Peters25a9ce32001-02-19 07:06:36 +0000192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 ADD_DEFINE(MB_OK);
194 ADD_DEFINE(MB_ICONASTERISK);
195 ADD_DEFINE(MB_ICONEXCLAMATION);
196 ADD_DEFINE(MB_ICONHAND);
197 ADD_DEFINE(MB_ICONQUESTION);
198 return module;
Guido van Rossume6005781999-02-04 22:40:42 +0000199}