blob: d61dde702bc3e7148344b81d7385ea70770151b1 [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örwaldfee10042003-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
Hirokazu Yamamoto62fbdd92010-11-07 02:45:19 +000080 if (!PyArg_ParseTuple(args, "z#i:PlaySound", &sound, &length, &flags)) {
81 return NULL;
Guido van Rossume6005781999-02-04 22:40:42 +000082 }
83
Hirokazu Yamamoto62fbdd92010-11-07 02:45:19 +000084 if (flags & SND_ASYNC && flags & SND_MEMORY) {
85 /* 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
Hirokazu Yamamoto62fbdd92010-11-07 02:45:19 +000092 ok = PlaySound(sound, NULL, flags);
Guido van Rossume6005781999-02-04 22:40:42 +000093 Py_END_ALLOW_THREADS
Hirokazu Yamamoto62fbdd92010-11-07 02:45:19 +000094 if (!ok) {
95 PyErr_SetString(PyExc_RuntimeError, "Failed to play sound");
96 return NULL;
Guido van Rossume6005781999-02-04 22:40:42 +000097 }
98
99 Py_INCREF(Py_None);
100 return Py_None;
101}
102
Tim Peters25a9ce32001-02-19 07:06:36 +0000103static PyObject *
104sound_beep(PyObject *self, PyObject *args)
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000105{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 int freq;
107 int dur;
108 BOOL ok;
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 if (!PyArg_ParseTuple(args, "ii:Beep", &freq, &dur))
111 return NULL;
Tim Peters25a9ce32001-02-19 07:06:36 +0000112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 if (freq < 37 || freq > 32767) {
114 PyErr_SetString(PyExc_ValueError,
115 "frequency must be in 37 thru 32767");
116 return NULL;
117 }
Tim Peters25a9ce32001-02-19 07:06:36 +0000118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 Py_BEGIN_ALLOW_THREADS
120 ok = Beep(freq, dur);
121 Py_END_ALLOW_THREADS
122 if (!ok) {
123 PyErr_SetString(PyExc_RuntimeError,"Failed to beep");
124 return NULL;
125 }
Tim Peters25a9ce32001-02-19 07:06:36 +0000126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 Py_INCREF(Py_None);
128 return Py_None;
Guido van Rossum99eb7a11999-10-01 14:29:17 +0000129}
130
Guido van Rossume1252682003-04-09 19:38:08 +0000131static PyObject *
132sound_msgbeep(PyObject *self, PyObject *args)
133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 int x = MB_OK;
135 if (!PyArg_ParseTuple(args, "|i:MessageBeep", &x))
136 return NULL;
137 MessageBeep(x);
138 Py_INCREF(Py_None);
139 return Py_None;
Guido van Rossume1252682003-04-09 19:38:08 +0000140}
141
Guido van Rossume6005781999-02-04 22:40:42 +0000142static struct PyMethodDef sound_methods[] =
143{
Neal Norwitz031829d2002-03-31 14:37:44 +0000144 {"PlaySound", sound_playsound, METH_VARARGS, sound_playsound_doc},
145 {"Beep", sound_beep, METH_VARARGS, sound_beep_doc},
Guido van Rossume1252682003-04-09 19:38:08 +0000146 {"MessageBeep", sound_msgbeep, METH_VARARGS, sound_msgbeep_doc},
Guido van Rossume6005781999-02-04 22:40:42 +0000147 {NULL, NULL}
148};
149
Tim Peters25a9ce32001-02-19 07:06:36 +0000150static void
151add_define(PyObject *dict, const char *key, long value)
Guido van Rossume6005781999-02-04 22:40:42 +0000152{
Hirokazu Yamamoto62fbdd92010-11-07 02:45:19 +0000153 PyObject *k = PyUnicode_FromString(key);
154 PyObject *v = PyLong_FromLong(value);
155 if (v && k) {
156 PyDict_SetItem(dict,k,v);
Guido van Rossume6005781999-02-04 22:40:42 +0000157 }
158 Py_XDECREF(k);
159 Py_XDECREF(v);
160}
161
162#define ADD_DEFINE(tok) add_define(dict,#tok,tok)
163
Martin v. Löwis1a214512008-06-11 05:26:20 +0000164
165static struct PyModuleDef winsoundmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 PyModuleDef_HEAD_INIT,
167 "winsound",
168 sound_module_doc,
169 -1,
170 sound_methods,
171 NULL,
172 NULL,
173 NULL,
174 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000175};
176
Mark Hammonde407e2a2002-07-22 13:26:41 +0000177PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000178PyInit_winsound(void)
Guido van Rossume6005781999-02-04 22:40:42 +0000179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 PyObject *dict;
181 PyObject *module = PyModule_Create(&winsoundmodule);
182 if (module == NULL)
183 return NULL;
184 dict = PyModule_GetDict(module);
Tim Peters25a9ce32001-02-19 07:06:36 +0000185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 ADD_DEFINE(SND_ASYNC);
187 ADD_DEFINE(SND_NODEFAULT);
188 ADD_DEFINE(SND_NOSTOP);
189 ADD_DEFINE(SND_NOWAIT);
190 ADD_DEFINE(SND_ALIAS);
191 ADD_DEFINE(SND_FILENAME);
192 ADD_DEFINE(SND_MEMORY);
193 ADD_DEFINE(SND_PURGE);
194 ADD_DEFINE(SND_LOOP);
195 ADD_DEFINE(SND_APPLICATION);
Tim Peters25a9ce32001-02-19 07:06:36 +0000196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 ADD_DEFINE(MB_OK);
198 ADD_DEFINE(MB_ICONASTERISK);
199 ADD_DEFINE(MB_ICONEXCLAMATION);
200 ADD_DEFINE(MB_ICONHAND);
201 ADD_DEFINE(MB_ICONQUESTION);
202 return module;
Guido van Rossume6005781999-02-04 22:40:42 +0000203}