/* 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>

static char 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.\n";

static char 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.\n";

static char 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.\n";

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)

DL_EXPORT(void)
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;
}
