/* Hey Emacs, this is -*-C-*- 
 ******************************************************************************
 * linuxaudiodev.c -- Linux audio device for python.
 * 
 * Author          : Peter Bosch
 * Created On      : Thu Mar  2 21:10:33 2000
 * Last Modified By: Peter Bosch
 * Last Modified On: Fri Mar 24 11:27:00 2000
 * Status          : Unknown, Use with caution!
 * 
 * Unless other notices are present in any part of this file
 * explicitly claiming copyrights for other people and/or 
 * organizations, the contents of this file is fully copyright 
 * (C) 2000 Peter Bosch, all rights reserved.
 ******************************************************************************
 */

#include "Python.h"
#include "structmember.h"

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif

#include <sys/ioctl.h>
#include <linux/soundcard.h>

typedef unsigned long uint32_t;

typedef struct {
    PyObject_HEAD;
    int		x_fd;		/* The open file */
    int		x_icount;	/* Input count */
    int		x_ocount;	/* Output count */
    uint32_t	x_afmts;	/* Supported audio formats */
} lad_t;

static struct {
    int		a_bps;
    uint32_t	a_fmt;
} audio_types[] = {
    {  8, 	AFMT_MU_LAW },
    {  8,	AFMT_U8 },
    {  8, 	AFMT_S8 },
    { 16, 	AFMT_U16_BE },
    { 16, 	AFMT_U16_LE },
    { 16, 	AFMT_S16_BE },
    { 16, 	AFMT_S16_LE },
};


staticforward PyTypeObject Ladtype;

static PyObject *LinuxAudioError;

static lad_t *
newladobject(PyObject *arg)
{
    lad_t *xp;
    int fd, afmts, imode;
    char *mode;
    char *basedev;

    /* Check arg for r/w/rw */
    if (!PyArg_ParseTuple(arg, "s:open", &mode)) return NULL;
    if (strcmp(mode, "r") == 0)
        imode = 0;
    else if (strcmp(mode, "w") == 0)
        imode = 1;
    else {
        PyErr_SetString(LinuxAudioError, "Mode should be one of 'r', or 'w'");
        return NULL;
    }

    /* Open the correct device.  The base device name comes from the
     * AUDIODEV environment variable first, then /dev/audio.  The
     * control device tacks "ctl" onto the base device name.
     */
    basedev = getenv("AUDIODEV");
    if (!basedev)
        basedev = "/dev/dsp";

    if ((fd = open(basedev, imode)) < 0) {
        PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
        return NULL;
    }
    if (imode && ioctl(fd, SNDCTL_DSP_NONBLOCK, NULL) < 0) {
        PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
        return NULL;
    }
    if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) < 0) {
        PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
        return NULL;
    }
    /* Create and initialize the object */
    if ((xp = PyObject_New(lad_t, &Ladtype)) == NULL) {
        close(fd);
        return NULL;
    }
    xp->x_fd     = fd;
    xp->x_icount = xp->x_ocount = 0;
    xp->x_afmts  = afmts;
    return xp;
}

static void
lad_dealloc(lad_t *xp)
{
    /* if already closed, don't reclose it */
    if (xp->x_fd != -1)
	close(xp->x_fd);
    PyObject_Del(xp);
}

static PyObject *
lad_read(lad_t *self, PyObject *args)
{
    int size, count;
    char *cp;
    PyObject *rv;
	
    if (!PyArg_ParseTuple(args, "i:read", &size))
        return NULL;
    rv = PyString_FromStringAndSize(NULL, size);
    if (rv == NULL)
        return NULL;

    if (!(cp = PyString_AsString(rv))) {
        Py_DECREF(rv);
        return NULL;
    }
    if ((count = read(self->x_fd, cp, size)) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        Py_DECREF(rv);
        return NULL;
    }
    self->x_icount += count;
    return rv;
}

static PyObject *
lad_write(lad_t *self, PyObject *args)
{
    char *cp;
    int rv, size;
	
    if (!PyArg_ParseTuple(args, "s#:write", &cp, &size)) return NULL;

    while (size > 0) {
        if ((rv = write(self->x_fd, cp, size)) < 0) {
            PyErr_SetFromErrno(LinuxAudioError);
            return NULL;
        }
        self->x_ocount += rv;
        size           -= rv;
        cp             += rv;
    }
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
lad_close(lad_t *self, PyObject *args)
{
    if (!PyArg_ParseTuple(args, ":close")) return NULL;
    if (self->x_fd >= 0) {
        close(self->x_fd);
        self->x_fd = -1;
    }
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
lad_fileno(lad_t *self, PyObject *args)
{
    if (!PyArg_ParseTuple(args, ":fileno")) return NULL;
    return PyInt_FromLong(self->x_fd);
}

static PyObject *
lad_setparameters(lad_t *self, PyObject *args)
{
    int rate, ssize, nchannels, stereo, n, fmt;

    if (!PyArg_ParseTuple(args, "iiii:setparameters",
                          &rate, &ssize, &nchannels, &fmt))
        return NULL;
  
    if (rate < 0 || ssize < 0 || (nchannels != 1 && nchannels != 2)) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    if (ioctl(self->x_fd, SOUND_PCM_WRITE_RATE, &rate) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    if (ioctl(self->x_fd, SNDCTL_DSP_SAMPLESIZE, &ssize) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    stereo = (nchannels == 1)? 0: (nchannels == 2)? 1: -1;
    if (ioctl(self->x_fd, SNDCTL_DSP_STEREO, &stereo) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    for (n = 0; n != sizeof(audio_types) / sizeof(audio_types[0]); n++)
        if (fmt == audio_types[n].a_fmt)
            break;

    if (n == sizeof(audio_types) / sizeof(audio_types[0]) ||
        audio_types[n].a_bps != ssize ||
        (self->x_afmts & audio_types[n].a_fmt) == 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT, &audio_types[n].a_fmt) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    Py_INCREF(Py_None);
    return Py_None;
}

static int
_ssize(lad_t *self, int *nchannels, int *ssize)
{
    int fmt;

    fmt = 0;
    if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT, &fmt) < 0) 
        return -errno;

    switch (fmt) {
    case AFMT_MU_LAW:
    case AFMT_A_LAW:
    case AFMT_U8:
    case AFMT_S8:
        *ssize = sizeof(char);
        break;
    case AFMT_S16_LE:
    case AFMT_S16_BE:
    case AFMT_U16_LE:
    case AFMT_U16_BE:
        *ssize = sizeof(short);
        break;
    case AFMT_MPEG:
    case AFMT_IMA_ADPCM:
    default:
        return -EOPNOTSUPP;
    }
    *nchannels = 0;
    if (ioctl(self->x_fd, SNDCTL_DSP_CHANNELS, nchannels) < 0)
        return -errno;
    return 0;
}


/* bufsize returns the size of the hardware audio buffer in number 
   of samples */
static PyObject *
lad_bufsize(lad_t *self, PyObject *args)
{
    audio_buf_info ai;
    int nchannels, ssize;

    if (!PyArg_ParseTuple(args, ":bufsize")) return NULL;

    if (_ssize(self, &nchannels, &ssize) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    return PyInt_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize));
}

/* obufcount returns the number of samples that are available in the 
   hardware for playing */
static PyObject *
lad_obufcount(lad_t *self, PyObject *args)
{
    audio_buf_info ai;
    int nchannels, ssize;

    if (!PyArg_ParseTuple(args, ":obufcount"))
        return NULL;

    if (_ssize(self, &nchannels, &ssize) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    return PyInt_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) / 
                          (ssize * nchannels));
}

/* obufcount returns the number of samples that can be played without
   blocking */
static PyObject *
lad_obuffree(lad_t *self, PyObject *args)
{
    audio_buf_info ai;
    int nchannels, ssize;

    if (!PyArg_ParseTuple(args, ":obuffree"))
        return NULL;

    if (_ssize(self, &nchannels, &ssize) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    return PyInt_FromLong(ai.bytes / (ssize * nchannels));
}

/* Flush the device */
static PyObject *
lad_flush(lad_t *self, PyObject *args)
{
    if (!PyArg_ParseTuple(args, ":flush")) return NULL;

    if (ioctl(self->x_fd, SNDCTL_DSP_SYNC, NULL) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    Py_INCREF(Py_None);
    return Py_None;
}

static PyMethodDef lad_methods[] = {
    { "read",		(PyCFunction)lad_read, METH_VARARGS },
    { "write",		(PyCFunction)lad_write, METH_VARARGS },
    { "setparameters",	(PyCFunction)lad_setparameters, METH_VARARGS },
    { "bufsize",	(PyCFunction)lad_bufsize, METH_VARARGS },
    { "obufcount",	(PyCFunction)lad_obufcount, METH_VARARGS },
    { "obuffree",	(PyCFunction)lad_obuffree, METH_VARARGS },
    { "flush",		(PyCFunction)lad_flush, METH_VARARGS },
    { "close",		(PyCFunction)lad_close, METH_VARARGS },
    { "fileno",     	(PyCFunction)lad_fileno, METH_VARARGS },
    { NULL,		NULL}		/* sentinel */
};

static PyObject *
lad_getattr(lad_t *xp, char *name)
{
    return Py_FindMethod(lad_methods, (PyObject *)xp, name);
}

static PyTypeObject Ladtype = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,				/*ob_size*/
    "linux_audio_device",	/*tp_name*/
    sizeof(lad_t),		/*tp_size*/
    0,				/*tp_itemsize*/
    /* methods */
    (destructor)lad_dealloc,	/*tp_dealloc*/
    0,				/*tp_print*/
    (getattrfunc)lad_getattr,	/*tp_getattr*/
    0,				/*tp_setattr*/
    0,				/*tp_compare*/
    0,				/*tp_repr*/
};

static PyObject *
ladopen(PyObject *self, PyObject *args)
{
    return (PyObject *)newladobject(args);
}

static PyMethodDef linuxaudiodev_methods[] = {
    { "open", ladopen, METH_VARARGS },
    { 0, 0 },
};

void
initlinuxaudiodev(void)
{
    PyObject *m, *d, *x;
  
    m = Py_InitModule("linuxaudiodev", linuxaudiodev_methods);
    d = PyModule_GetDict(m);

    LinuxAudioError = PyErr_NewException("linuxaudiodev.error", NULL, NULL);
    if (LinuxAudioError)
        PyDict_SetItemString(d, "error", LinuxAudioError);

    x = PyInt_FromLong((long) AFMT_MU_LAW);
    if (x == NULL || PyDict_SetItemString(d, "AFMT_MU_LAW", x) < 0)
        goto error;
    Py_DECREF(x);

    x = PyInt_FromLong((long) AFMT_U8);
    if (x == NULL || PyDict_SetItemString(d, "AFMT_U8", x) < 0)
        goto error;
    Py_DECREF(x);

    x = PyInt_FromLong((long) AFMT_S8);
    if (x == NULL || PyDict_SetItemString(d, "AFMT_S8", x) < 0)
        goto error;
    Py_DECREF(x);

    x = PyInt_FromLong((long) AFMT_U16_BE);
    if (x == NULL || PyDict_SetItemString(d, "AFMT_U16_BE", x) < 0)
        goto error;
    Py_DECREF(x);

    x = PyInt_FromLong((long) AFMT_U16_LE);
    if (x == NULL || PyDict_SetItemString(d, "AFMT_U16_LE", x) < 0)
        goto error;
    Py_DECREF(x);

    x = PyInt_FromLong((long) AFMT_S16_BE);
    if (x == NULL || PyDict_SetItemString(d, "AFMT_S16_BE", x) < 0)
        goto error;
    Py_DECREF(x);

    x = PyInt_FromLong((long) AFMT_S16_LE);
    if (x == NULL || PyDict_SetItemString(d, "AFMT_S16_LE", x) < 0)
        goto error;
    Py_DECREF(x);

    /* Check for errors */
    if (PyErr_Occurred()) {
    error:
        Py_FatalError("can't initialize module linuxaudiodev");
    }
}
