blob: 4edda3f6af7c5b029eef89134fa715ce257c6737 [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{
75 const char *sound;
76 int flags;
77 int length;
78 int ok;
79
Tim Peters25a9ce32001-02-19 07:06:36 +000080 if(!PyArg_ParseTuple(args,"z#i:PlaySound",&sound,&length,&flags)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 return NULL;
Guido van Rossume6005781999-02-04 22:40:42 +000082 }
83
Tim Peters25a9ce32001-02-19 07:06:36 +000084 if(flags&SND_ASYNC && flags &SND_MEMORY) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 /* Sidestep reference counting headache; unfortunately this also
86 prevent SND_LOOP from memory. */
87 PyErr_SetString(PyExc_RuntimeError,"Cannot play asynchronously from memory");
88 return NULL;
Guido van Rossume6005781999-02-04 22:40:42 +000089 }
90
91 Py_BEGIN_ALLOW_THREADS
92 ok = PlaySound(sound,NULL,flags);
93 Py_END_ALLOW_THREADS
94 if(!ok)
95 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 PyErr_SetString(PyExc_RuntimeError,"Failed to play sound");
97 return NULL;
Guido van Rossume6005781999-02-04 22:40:42 +000098 }
99
100 Py_INCREF(Py_None);
101 return Py_None;
102}
103
Tim Peters25a9ce32001-02-19 07:06:36 +0000104static PyObject *
105sound_beep(PyObject *self, PyObject *args)
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000106{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 int freq;
108 int dur;
109 BOOL ok;
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 if (!PyArg_ParseTuple(args, "ii:Beep", &freq, &dur))
112 return NULL;
Tim Peters25a9ce32001-02-19 07:06:36 +0000113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 if (freq < 37 || freq > 32767) {
115 PyErr_SetString(PyExc_ValueError,
116 "frequency must be in 37 thru 32767");
117 return NULL;
118 }
Tim Peters25a9ce32001-02-19 07:06:36 +0000119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 Py_BEGIN_ALLOW_THREADS
121 ok = Beep(freq, dur);
122 Py_END_ALLOW_THREADS
123 if (!ok) {
124 PyErr_SetString(PyExc_RuntimeError,"Failed to beep");
125 return NULL;
126 }
Tim Peters25a9ce32001-02-19 07:06:36 +0000127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 Py_INCREF(Py_None);
129 return Py_None;
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000130}
131
Guido van Rossume1252682003-04-09 19:38:08 +0000132static PyObject *
133sound_msgbeep(PyObject *self, PyObject *args)
134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 int x = MB_OK;
136 if (!PyArg_ParseTuple(args, "|i:MessageBeep", &x))
137 return NULL;
138 MessageBeep(x);
139 Py_INCREF(Py_None);
140 return Py_None;
Guido van Rossume1252682003-04-09 19:38:08 +0000141}
142
Guido van Rossume6005781999-02-04 22:40:42 +0000143static struct PyMethodDef sound_methods[] =
144{
Neal Norwitz031829d2002-03-31 14:37:44 +0000145 {"PlaySound", sound_playsound, METH_VARARGS, sound_playsound_doc},
146 {"Beep", sound_beep, METH_VARARGS, sound_beep_doc},
Guido van Rossume1252682003-04-09 19:38:08 +0000147 {"MessageBeep", sound_msgbeep, METH_VARARGS, sound_msgbeep_doc},
Guido van Rossume6005781999-02-04 22:40:42 +0000148 {NULL, NULL}
149};
150
Tim Peters25a9ce32001-02-19 07:06:36 +0000151static void
152add_define(PyObject *dict, const char *key, long value)
Guido van Rossume6005781999-02-04 22:40:42 +0000153{
Neal Norwitza369c5a2007-08-25 07:41:59 +0000154 PyObject *k=PyUnicode_FromString(key);
Guido van Rossume6005781999-02-04 22:40:42 +0000155 PyObject *v=PyLong_FromLong(value);
156 if(v&&k)
157 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 PyDict_SetItem(dict,k,v);
Guido van Rossume6005781999-02-04 22:40:42 +0000159 }
160 Py_XDECREF(k);
161 Py_XDECREF(v);
162}
163
164#define ADD_DEFINE(tok) add_define(dict,#tok,tok)
165
Martin v. Löwis1a214512008-06-11 05:26:20 +0000166
167static struct PyModuleDef winsoundmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 PyModuleDef_HEAD_INIT,
169 "winsound",
170 sound_module_doc,
171 -1,
172 sound_methods,
173 NULL,
174 NULL,
175 NULL,
176 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000177};
178
Mark Hammonde407e2a2002-07-22 13:26:41 +0000179PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000180PyInit_winsound(void)
Guido van Rossume6005781999-02-04 22:40:42 +0000181{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 PyObject *dict;
183 PyObject *module = PyModule_Create(&winsoundmodule);
184 if (module == NULL)
185 return NULL;
186 dict = PyModule_GetDict(module);
Tim Peters25a9ce32001-02-19 07:06:36 +0000187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 ADD_DEFINE(SND_ASYNC);
189 ADD_DEFINE(SND_NODEFAULT);
190 ADD_DEFINE(SND_NOSTOP);
191 ADD_DEFINE(SND_NOWAIT);
192 ADD_DEFINE(SND_ALIAS);
193 ADD_DEFINE(SND_FILENAME);
194 ADD_DEFINE(SND_MEMORY);
195 ADD_DEFINE(SND_PURGE);
196 ADD_DEFINE(SND_LOOP);
197 ADD_DEFINE(SND_APPLICATION);
Tim Peters25a9ce32001-02-19 07:06:36 +0000198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 ADD_DEFINE(MB_OK);
200 ADD_DEFINE(MB_ICONASTERISK);
201 ADD_DEFINE(MB_ICONEXCLAMATION);
202 ADD_DEFINE(MB_ICONHAND);
203 ADD_DEFINE(MB_ICONQUESTION);
204 return module;
Guido van Rossume6005781999-02-04 22:40:42 +0000205}