/* Author: Toby Dickenson <htrd90@zepler.org>
 *
 * Copyright (c) 1999 Toby Dickenson
 *
 * Permission to use this software in any way is granted without
 * fee, provided that the copyright notice above appears in all
 * copies. This software is provided "as is" without any warranty.
 */

/* Modified by Guido van Rossum */
/* Beep added by Mark Hammond */
/* Win9X Beep and platform identification added by Uncle Timmy */

/* Example:

   import winsound
   import time

   # Play wav file
   winsound.PlaySound('c:/windows/media/Chord.wav', winsound.SND_FILENAME)

   # Play sound from control panel settings
   winsound.PlaySound('SystemQuestion', winsound.SND_ALIAS)

   # Play wav file from memory
   data=open('c:/windows/media/Chimes.wav',"rb").read()
   winsound.PlaySound(data, winsound.SND_MEMORY)

   # Start playing the first bit of wav file asynchronously
   winsound.PlaySound('c:/windows/media/Chord.wav',
                   winsound.SND_FILENAME|winsound.SND_ASYNC)
   # But dont let it go for too long...
   time.sleep(0.1)
   # ...Before stopping it
   winsound.PlaySound(None, 0)
*/

#include <windows.h>
#include <mmsystem.h>
#include <conio.h>	/* port functions on Win9x */
#include <Python.h>

PyDoc_STRVAR(sound_playsound_doc,
"PlaySound(sound, flags) - a wrapper around the Windows PlaySound API\n"
"\n"
"The sound argument can be a filename, data, or None.\n"
"For flag values, ored together, see module documentation.");

PyDoc_STRVAR(sound_beep_doc,
"Beep(frequency, duration) - a wrapper around the Windows Beep API\n"
"\n"
"The frequency argument specifies frequency, in hertz, of the sound.\n"
"This parameter must be in the range 37 through 32,767.\n"
"The duration argument specifies the number of milliseconds.\n"
"On WinNT and 2000, the platform Beep API is used directly.  Else funky\n"
"code doing direct port manipulation is used; it's unknown whether that\n"
"will work on all systems.");

PyDoc_STRVAR(sound_module_doc,
"PlaySound(sound, flags) - play a sound\n"
"SND_FILENAME - sound is a wav file name\n"
"SND_ALIAS - sound is a registry sound association name\n"
"SND_LOOP - Play the sound repeatedly; must also specify SND_ASYNC\n"
"SND_MEMORY - sound is a memory image of a wav file\n"
"SND_PURGE - stop all instances of the specified sound\n"
"SND_ASYNC - PlaySound returns immediately\n"
"SND_NODEFAULT - Do not play a default beep if the sound can not be found\n"
"SND_NOSTOP - Do not interrupt any sounds currently playing\n"  // Raising RuntimeError if needed
"SND_NOWAIT - Return immediately if the sound driver is busy\n" // Without any errors
"\n"
"Beep(frequency, duration) - Make a beep through the PC speaker.");

PyObject *
sound_playsound(PyObject *s, PyObject *args)
{
    const char *sound;
    int flags;
    int length;
    int ok;

    if(!PyArg_ParseTuple(args,"z#i:PlaySound",&sound,&length,&flags)) {
        return NULL;
    }

    if(flags&SND_ASYNC && flags &SND_MEMORY) {
	/* Sidestep reference counting headache; unfortunately this also
	   prevent SND_LOOP from memory. */
        PyErr_SetString(PyExc_RuntimeError,"Cannot play asynchronously from memory");
        return NULL;
    }

    Py_BEGIN_ALLOW_THREADS
    ok = PlaySound(sound,NULL,flags);
    Py_END_ALLOW_THREADS
    if(!ok)
    {
        PyErr_SetString(PyExc_RuntimeError,"Failed to play sound");
        return NULL;
    }

    Py_INCREF(Py_None);
    return Py_None;
}

enum OSType {Win9X, WinNT2000};
static enum OSType whichOS;	/* set by module init */

static PyObject *
sound_beep(PyObject *self, PyObject *args)
{
	int freq;
	int dur;

	if (!PyArg_ParseTuple(args, "ii:Beep", &freq,  &dur))
		return NULL;

	if (freq < 37 || freq > 32767) {
		PyErr_SetString(PyExc_ValueError,
				"frequency must be in 37 thru 32767");
		return NULL;
	}

	/* On NT and 2000, the SDK Beep() function does the whole job.
	 * But while Beep() exists before NT, it ignores its arguments and
	 * plays the system default sound.  Sheesh ...
	 * The Win9X code is mondo bizarre.  I (Tim) pieced it together from
	 * crap all over the web.  The original IBM PC used some particular
	 * pieces of hardware (Intel 8255 and 8254 chips) hardwired to
	 * particular port addresses and running at particular clock speeds,
	 * and the poor sound card folks have been forced to emulate that in
	 * all particulars ever since.  But NT and 2000 don't support port
	 * manipulation.  Don't know about WinME; guessing it's like 98.
	 */

	if (whichOS == WinNT2000) {
		BOOL ok;
		Py_BEGIN_ALLOW_THREADS
		ok = Beep(freq, dur);
		Py_END_ALLOW_THREADS
		if (!ok) {
			PyErr_SetString(PyExc_RuntimeError,"Failed to beep");
			return NULL;
		}
	}
	else if (whichOS == Win9X) {
		int speaker_state;
		/* Force timer into oscillator mode via timer control port. */
		_outp(0x43, 0xb6);
		/* Compute ratio of ancient hardcoded timer frequency to
		 * frequency we want.  Then feed that ratio (lowest byte
		 * first) into timer data port.
		 */
		freq = 1193180 / freq;
		_outp(0x42, freq & 0xff);
		_outp(0x42, (freq >> 8) & 0xff);
		/* Get speaker control state. */
		speaker_state = _inp(0x61);
		/* Turn the speaker on (bit 1)
		 * and drive speaker from timer (bit 0).
		 */
		_outp(0x61, speaker_state | 0x3);
		/* Let it blast in peace for the duration. */
		Py_BEGIN_ALLOW_THREADS
		Sleep(dur);
		Py_END_ALLOW_THREADS
		/* Restore speaker control to original state. */
		_outp(0x61, speaker_state);
	}
	else {
		assert(!"winsound's whichOS has insane value");
	}
	Py_INCREF(Py_None);
	return Py_None;
}

static struct PyMethodDef sound_methods[] =
{
    {"PlaySound", sound_playsound, METH_VARARGS, sound_playsound_doc},
    {"Beep",      sound_beep,      METH_VARARGS, sound_beep_doc},
    {NULL,  NULL}
};

static void
add_define(PyObject *dict, const char *key, long value)
{
    PyObject *k=PyString_FromString(key);
    PyObject *v=PyLong_FromLong(value);
    if(v&&k)
    {
        PyDict_SetItem(dict,k,v);
    }
    Py_XDECREF(k);
    Py_XDECREF(v);
}

#define ADD_DEFINE(tok) add_define(dict,#tok,tok)

PyMODINIT_FUNC
initwinsound(void)
{
	OSVERSIONINFO version;

	PyObject *module = Py_InitModule3("winsound",
					  sound_methods,
					  sound_module_doc);
	PyObject *dict = PyModule_GetDict(module);

	ADD_DEFINE(SND_ASYNC);
	ADD_DEFINE(SND_NODEFAULT);
	ADD_DEFINE(SND_NOSTOP);
	ADD_DEFINE(SND_NOWAIT);
	ADD_DEFINE(SND_ALIAS);
	ADD_DEFINE(SND_FILENAME);
	ADD_DEFINE(SND_MEMORY);
	ADD_DEFINE(SND_PURGE);
	ADD_DEFINE(SND_LOOP);
	ADD_DEFINE(SND_APPLICATION);

	version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&version);
	whichOS = Win9X;
	if (version.dwPlatformId != VER_PLATFORM_WIN32s &&
	    version.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
		whichOS = WinNT2000;
}
