|
1 /* 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 */ |
|
11 /* Beep added by Mark Hammond */ |
|
12 /* Win9X Beep and platform identification added by Uncle Timmy */ |
|
13 |
|
14 /* Example: |
|
15 |
|
16 import winsound |
|
17 import time |
|
18 |
|
19 # Play wav file |
|
20 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 |
|
38 #include <Python.h> |
|
39 #include <windows.h> |
|
40 #include <mmsystem.h> |
|
41 |
|
42 PyDoc_STRVAR(sound_playsound_doc, |
|
43 "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" |
|
46 "For flag values, ored together, see module documentation."); |
|
47 |
|
48 PyDoc_STRVAR(sound_beep_doc, |
|
49 "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" |
|
52 "This parameter must be in the range 37 through 32,767.\n" |
|
53 "The duration argument specifies the number of milliseconds.\n"); |
|
54 |
|
55 PyDoc_STRVAR(sound_msgbeep_doc, |
|
56 "MessageBeep(x) - call Windows MessageBeep(x). x defaults to MB_OK."); |
|
57 |
|
58 PyDoc_STRVAR(sound_module_doc, |
|
59 "PlaySound(sound, flags) - play a sound\n" |
|
60 "SND_FILENAME - sound is a wav file name\n" |
|
61 "SND_ALIAS - sound is a registry sound association name\n" |
|
62 "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 |
|
69 "\n" |
|
70 "Beep(frequency, duration) - Make a beep through the PC speaker."); |
|
71 |
|
72 static PyObject * |
|
73 sound_playsound(PyObject *s, PyObject *args) |
|
74 { |
|
75 const char *sound; |
|
76 int flags; |
|
77 int length; |
|
78 int ok; |
|
79 |
|
80 if(!PyArg_ParseTuple(args,"z#i:PlaySound",&sound,&length,&flags)) { |
|
81 return NULL; |
|
82 } |
|
83 |
|
84 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; |
|
89 } |
|
90 |
|
91 Py_BEGIN_ALLOW_THREADS |
|
92 ok = PlaySound(sound,NULL,flags); |
|
93 Py_END_ALLOW_THREADS |
|
94 if(!ok) |
|
95 { |
|
96 PyErr_SetString(PyExc_RuntimeError,"Failed to play sound"); |
|
97 return NULL; |
|
98 } |
|
99 |
|
100 Py_INCREF(Py_None); |
|
101 return Py_None; |
|
102 } |
|
103 |
|
104 static PyObject * |
|
105 sound_beep(PyObject *self, PyObject *args) |
|
106 { |
|
107 int freq; |
|
108 int dur; |
|
109 BOOL ok; |
|
110 |
|
111 if (!PyArg_ParseTuple(args, "ii:Beep", &freq, &dur)) |
|
112 return NULL; |
|
113 |
|
114 if (freq < 37 || freq > 32767) { |
|
115 PyErr_SetString(PyExc_ValueError, |
|
116 "frequency must be in 37 thru 32767"); |
|
117 return NULL; |
|
118 } |
|
119 |
|
120 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 } |
|
127 |
|
128 Py_INCREF(Py_None); |
|
129 return Py_None; |
|
130 } |
|
131 |
|
132 static PyObject * |
|
133 sound_msgbeep(PyObject *self, PyObject *args) |
|
134 { |
|
135 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; |
|
141 } |
|
142 |
|
143 static struct PyMethodDef sound_methods[] = |
|
144 { |
|
145 {"PlaySound", sound_playsound, METH_VARARGS, sound_playsound_doc}, |
|
146 {"Beep", sound_beep, METH_VARARGS, sound_beep_doc}, |
|
147 {"MessageBeep", sound_msgbeep, METH_VARARGS, sound_msgbeep_doc}, |
|
148 {NULL, NULL} |
|
149 }; |
|
150 |
|
151 static void |
|
152 add_define(PyObject *dict, const char *key, long value) |
|
153 { |
|
154 PyObject *k=PyString_FromString(key); |
|
155 PyObject *v=PyLong_FromLong(value); |
|
156 if(v&&k) |
|
157 { |
|
158 PyDict_SetItem(dict,k,v); |
|
159 } |
|
160 Py_XDECREF(k); |
|
161 Py_XDECREF(v); |
|
162 } |
|
163 |
|
164 #define ADD_DEFINE(tok) add_define(dict,#tok,tok) |
|
165 |
|
166 PyMODINIT_FUNC |
|
167 initwinsound(void) |
|
168 { |
|
169 PyObject *dict; |
|
170 PyObject *module = Py_InitModule3("winsound", |
|
171 sound_methods, |
|
172 sound_module_doc); |
|
173 if (module == NULL) |
|
174 return; |
|
175 dict = PyModule_GetDict(module); |
|
176 |
|
177 ADD_DEFINE(SND_ASYNC); |
|
178 ADD_DEFINE(SND_NODEFAULT); |
|
179 ADD_DEFINE(SND_NOSTOP); |
|
180 ADD_DEFINE(SND_NOWAIT); |
|
181 ADD_DEFINE(SND_ALIAS); |
|
182 ADD_DEFINE(SND_FILENAME); |
|
183 ADD_DEFINE(SND_MEMORY); |
|
184 ADD_DEFINE(SND_PURGE); |
|
185 ADD_DEFINE(SND_LOOP); |
|
186 ADD_DEFINE(SND_APPLICATION); |
|
187 |
|
188 ADD_DEFINE(MB_OK); |
|
189 ADD_DEFINE(MB_ICONASTERISK); |
|
190 ADD_DEFINE(MB_ICONEXCLAMATION); |
|
191 ADD_DEFINE(MB_ICONHAND); |
|
192 ADD_DEFINE(MB_ICONQUESTION); |
|
193 } |