blob: 2654172809349c3ea7d37014c903b3dc0cccbbbc [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 */
11
12/* Example:
13
14 import winsound
15 import time
16
17 # Play wav file
18 winsound.PlaySound('c:/windows/media/Chord.wav', winsound.SND_FILENAME)
19
20 # Play sound from control panel settings
21 winsound.PlaySound('SystemQuestion', winsound.SND_ALIAS)
22
23 # Play wav file from memory
24 data=open('c:/windows/media/Chimes.wav',"rb").read()
25 winsound.PlaySound(data, winsound.SND_MEMORY)
26
27 # Start playing the first bit of wav file asynchronously
28 winsound.PlaySound('c:/windows/media/Chord.wav',
29 winsound.SND_FILENAME|winsound.SND_ASYNC)
30 # But dont let it go for too long...
31 time.sleep(0.1)
32 # ...Before stopping it
33 winsound.PlaySound(None, 0)
34*/
35
36#include <windows.h>
37#include <mmsystem.h>
38#include <Python.h>
39
40static char sound_playsound_doc[] =
41"PlaySound(sound, flags) - a wrapper around the Windows PlaySound API\n"
42"\n"
43"The sound argument can be a filename, data, or None.\n"
44"For flag values, ored together, see module documentation.\n";
45
46static char sound_module_doc[] =
47"PlaySound(sound, flags) - play a sound\n"
48"SND_FILENAME - sound is a wav file name\n"
49"SND_ALIAS - sound is a control panel sound association name\n"
50"SND_LOOP - Play the sound repeatedly; must also specify SND_ASYNC\n"
51"SND_MEMORY - sound is a memory image of a wav file\n"
52"SND_PURGE - stop all instances of the specified sound\n"
53"SND_ASYNC - PlaySound returns immediately\n"
54"SND_NODEFAULT - Do not play a default beep if the sound can not be found\n"
55"SND_NOSTOP - Do not interrupt any sounds currently playing\n" // Raising RuntimeError if needed
56"SND_NOWAIT - Return immediately if the sound driver is busy\n" // Without any errors
57;
58
59PyObject *sound_playsound(PyObject *s, PyObject *args)
60{
61 const char *sound;
62 int flags;
63 int length;
64 int ok;
65
66 if(!PyArg_ParseTuple(args,"z#i:PlaySound",&sound,&length,&flags))
67 {
68 return NULL;
69 }
70
71 if(flags&SND_ASYNC && flags &SND_MEMORY)
72 {
73 /* Sidestep reference counting headache; unfortunately this also
74 prevent SND_LOOP from memory. */
75 PyErr_SetString(PyExc_RuntimeError,"Cannot play asynchronously from memory");
76 return NULL;
77 }
78
79 Py_BEGIN_ALLOW_THREADS
80 ok = PlaySound(sound,NULL,flags);
81 Py_END_ALLOW_THREADS
82 if(!ok)
83 {
84 PyErr_SetString(PyExc_RuntimeError,"Failed to play sound");
85 return NULL;
86 }
87
88 Py_INCREF(Py_None);
89 return Py_None;
90}
91
92static struct PyMethodDef sound_methods[] =
93{
94 {"PlaySound", sound_playsound, 1, sound_playsound_doc},
95 {NULL, NULL}
96};
97
98static void add_define(PyObject *dict, const char *key, long value)
99{
100 PyObject *k=PyString_FromString(key);
101 PyObject *v=PyLong_FromLong(value);
102 if(v&&k)
103 {
104 PyDict_SetItem(dict,k,v);
105 }
106 Py_XDECREF(k);
107 Py_XDECREF(v);
108}
109
110#define ADD_DEFINE(tok) add_define(dict,#tok,tok)
111
112DL_EXPORT(void)
113initwinsound()
114{
115 PyObject *module=Py_InitModule3("winsound", sound_methods, sound_module_doc);
116 PyObject *dict=PyModule_GetDict(module);
117
118 ADD_DEFINE(SND_ASYNC);
119 ADD_DEFINE(SND_NODEFAULT);
120 ADD_DEFINE(SND_NOSTOP);
121 ADD_DEFINE(SND_NOWAIT);
122 ADD_DEFINE(SND_ALIAS);
123 ADD_DEFINE(SND_FILENAME);
124 ADD_DEFINE(SND_MEMORY);
125 ADD_DEFINE(SND_PURGE);
126 ADD_DEFINE(SND_LOOP);
127 ADD_DEFINE(SND_APPLICATION);
128}