/* Hey Emacs, this is -*-C-*- 
 ******************************************************************************
 * linuxaudiodev.c -- Linux audio device for python.
 * 
 * Author          : Peter Bosch
 * Created On      : Thu Mar  2 21:10:33 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>
#else
#define O_RDONLY 00
#define O_WRONLY 01
#endif


#include <sys/ioctl.h>
#if defined(linux)
#include <linux/soundcard.h>

typedef unsigned long uint32_t;

#elif defined(__FreeBSD__)
#include <machine/soundcard.h>

#ifndef SNDCTL_DSP_CHANNELS
#define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS
#endif

#endif

typedef struct {
    PyObject_HEAD;
    int		x_fd;		/* The open file */
    int         x_mode;           /* file mode */
    int		x_icount;	/* Input count */
    int		x_ocount;	/* Output count */
    uint32_t	x_afmts;	/* Audio formats supported by hardware*/
} lad_t;

/* XXX several format defined in soundcard.h are not supported,
   including _NE (native endian) options and S32 options
*/

static struct {
    int		a_bps;
    uint32_t	a_fmt;
    char       *a_name;
} audio_types[] = {
    {  8, 	AFMT_MU_LAW, "logarithmic mu-law 8-bit audio" },
    {  8, 	AFMT_A_LAW,  "logarithmic A-law 8-bit audio" },
    {  8,	AFMT_U8,     "linear unsigned 8-bit audio" },
    {  8, 	AFMT_S8,     "linear signed 8-bit audio" },
    { 16, 	AFMT_U16_BE, "linear unsigned 16-bit big-endian audio" },
    { 16, 	AFMT_U16_LE, "linear unsigned 16-bit little-endian audio" },
    { 16, 	AFMT_S16_BE, "linear signed 16-bit big-endian audio" },
    { 16, 	AFMT_S16_LE, "linear signed 16-bit little-endian audio" },
    { 16, 	AFMT_S16_NE, "linear signed 16-bit native-endian audio" },
};

static int n_audio_types = sizeof(audio_types) / sizeof(audio_types[0]);

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 = O_RDONLY;
    else if (strcmp(mode, "w") == 0)
        imode = O_WRONLY;
    else {
        PyErr_SetString(LinuxAudioError, "mode should be 'r' or 'w'");
        return NULL;
    }

    /* Open the correct device.  The base device name comes from the
     * AUDIODEV environment variable first, then /dev/dsp.  The
     * control device tacks "ctl" onto the base device name.
     * 
     * Note that the only difference between /dev/audio and /dev/dsp
     * is that the former uses logarithmic mu-law encoding and the
     * latter uses 8-bit unsigned encoding.
     */

    basedev = getenv("AUDIODEV");
    if (!basedev)
        basedev = "/dev/dsp";

    if ((fd = open(basedev, imode)) == -1) {
        PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
        return NULL;
    }
    if (imode == O_WRONLY && ioctl(fd, SNDCTL_DSP_NONBLOCK, NULL) == -1) {
        PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
        return NULL;
    }
    if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) {
        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_mode = imode;
    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;
    cp = PyString_AS_STRING(rv);
    if ((count = read(self->x_fd, cp, size)) < 0) {
        PyErr_SetFromErrno(LinuxAudioError);
        Py_DECREF(rv);
        return NULL;
    }
    self->x_icount += count;
    if (_PyString_Resize(&rv, count) == -1)
	return NULL;
    return rv;
}

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

    /* use select to wait for audio device to be available */
    FD_ZERO(&write_set_fds);
    FD_SET(self->x_fd, &write_set_fds);
    tv.tv_sec = 4; /* timeout values */
    tv.tv_usec = 0; 

    while (size > 0) {
      select_retval = select(self->x_fd+1, NULL, &write_set_fds, NULL, &tv);
      tv.tv_sec = 1; tv.tv_usec = 0; /* willing to wait this long next time*/
      if (select_retval) {
        if ((rv = write(self->x_fd, cp, size)) == -1) {
	  if (errno != EAGAIN) {
	    PyErr_SetFromErrno(LinuxAudioError);
	    return NULL;
	  } else {
	    errno = 0; /* EAGAIN: buffer is full, try again */
	  }
        } else {
	  self->x_ocount += rv;
	  size -= rv;
	  cp += rv;
	}
      } else {
	/* printf("Not able to write to linux audio device within %ld seconds\n", tv.tv_sec); */
	PyErr_SetFromErrno(LinuxAudioError);
	return NULL;
      }
    }
    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, n, fmt, emulate=0;

    if (!PyArg_ParseTuple(args, "iiii|i:setparameters",
                          &rate, &ssize, &nchannels, &fmt, &emulate))
        return NULL;
  
    if (rate < 0) {
	PyErr_Format(PyExc_ValueError, "expected rate >= 0, not %d",
		     rate); 
	return NULL;
    }
    if (ssize < 0) {
	PyErr_Format(PyExc_ValueError, "expected sample size >= 0, not %d",
		     ssize);
	return NULL;
    }
    if (nchannels != 1 && nchannels != 2) {
	PyErr_Format(PyExc_ValueError, "nchannels must be 1 or 2, not %d",
		     nchannels);
	return NULL;
    }

    if (ioctl(self->x_fd, SNDCTL_DSP_SPEED, &rate) == -1) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    if (ioctl(self->x_fd, SNDCTL_DSP_CHANNELS, &nchannels) == -1) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }

    for (n = 0; n < n_audio_types; n++)
        if (fmt == audio_types[n].a_fmt)
            break;
    if (n == n_audio_types) {
	PyErr_Format(PyExc_ValueError, "unknown audio encoding: %d", fmt);
	return NULL;
    }
    if (audio_types[n].a_bps != ssize) {
	PyErr_Format(PyExc_ValueError, 
		     "for %s, expected sample size %d, not %d",
		     audio_types[n].a_name, audio_types[n].a_bps, ssize);
	return NULL;
    }

    if (emulate == 0) {
	if ((self->x_afmts & audio_types[n].a_fmt) == 0) {
	    PyErr_Format(PyExc_ValueError, 
			 "%s format not supported by device",
			 audio_types[n].a_name);
	    return NULL;
	}
    }
    if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT, 
	      &audio_types[n].a_fmt) == -1) {
        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) == -1) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
lad_getptr(lad_t *self, PyObject *args)
{
    count_info info;
    int req;

    if (!PyArg_ParseTuple(args, ":getptr"))
	return NULL;
    
    if (self->x_mode == O_RDONLY)
	req = SNDCTL_DSP_GETIPTR;
    else
	req = SNDCTL_DSP_GETOPTR;
    if (ioctl(self->x_fd, req, &info) == -1) {
        PyErr_SetFromErrno(LinuxAudioError);
        return NULL;
    }
    return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr);
}

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 },
    { "getptr",         (PyCFunction)lad_getptr, 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;
  
    m = Py_InitModule("linuxaudiodev", linuxaudiodev_methods);

    LinuxAudioError = PyErr_NewException("linuxaudiodev.error", NULL, NULL);
    if (LinuxAudioError)
	PyModule_AddObject(m, "error", LinuxAudioError);

    if (PyModule_AddIntConstant(m, "AFMT_MU_LAW", (long)AFMT_MU_LAW) == -1)
	return;
    if (PyModule_AddIntConstant(m, "AFMT_A_LAW", (long)AFMT_A_LAW) == -1)
	return;
    if (PyModule_AddIntConstant(m, "AFMT_U8", (long)AFMT_U8) == -1)
	return;
    if (PyModule_AddIntConstant(m, "AFMT_S8", (long)AFMT_S8) == -1)
	return;
    if (PyModule_AddIntConstant(m, "AFMT_U16_BE", (long)AFMT_U16_BE) == -1)
	return;
    if (PyModule_AddIntConstant(m, "AFMT_U16_LE", (long)AFMT_U16_LE) == -1)
	return;
    if (PyModule_AddIntConstant(m, "AFMT_S16_BE", (long)AFMT_S16_BE) == -1)
	return;
    if (PyModule_AddIntConstant(m, "AFMT_S16_LE", (long)AFMT_S16_LE) == -1)
	return;
    if (PyModule_AddIntConstant(m, "AFMT_S16_NE", (long)AFMT_S16_NE) == -1)
	return;

    return;
}
