diff --git a/alsaaudio.c b/alsaaudio.c index 80a8849..f2d77b4 100644 --- a/alsaaudio.c +++ b/alsaaudio.c @@ -1,4 +1,4 @@ -/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * alsaaudio -- Python interface to ALSA (Advanced Linux Sound Architecture). @@ -29,47 +29,45 @@ PyDoc_STRVAR(alsaaudio_module_doc, "are controlled using the Mixer class.\n" "\n" "The following functions are also provided:\n" - "mixers() -- Return a list of available mixer names\n" - ); + "mixers() -- Return a list of available mixer names\n"); typedef struct { - PyObject_HEAD; - int pcmtype; - int pcmmode; - char *cardname; + PyObject_HEAD; + int pcmtype; + int pcmmode; + char *cardname; - snd_pcm_t *handle; + snd_pcm_t *handle; - // Configurable parameters - int channels; - int rate; - int format; - snd_pcm_uframes_t periodsize; - int framesize; + // Configurable parameters + int channels; + int rate; + int format; + snd_pcm_uframes_t periodsize; + int framesize; } alsapcm_t; typedef struct { - PyObject_HEAD; - - /* Mixer identification */ - char *cardname; - char *controlname; - int controlid; - - /* Capabilities */ - unsigned int volume_cap; - unsigned int switch_cap; - unsigned int pchannels; - unsigned int cchannels; - - /* min and max values for playback and capture volumes */ - long pmin; - long pmax; - long cmin; - long cmax; - snd_mixer_t *handle; + PyObject_HEAD; + /* Mixer identification */ + char *cardname; + char *controlname; + int controlid; + + /* Capabilities */ + unsigned int volume_cap; + unsigned int switch_cap; + unsigned int pchannels; + unsigned int cchannels; + + /* min and max values for playback and capture volumes */ + long pmin; + long pmax; + long cmin; + long cmax; + snd_mixer_t *handle; } alsamixer_t; /* Translate a card id to a ALSA cardname @@ -78,20 +76,20 @@ typedef struct { */ char *translate_cardname(char *name) { - static char dflt[] = "default"; - char *full = NULL; + static char dflt[] = "default"; + char *full = NULL; + + if (!name || !strcmp(name, dflt)) + return strdup(dflt); + + // If we find a colon, we assume it is a real ALSA cardname + if (strchr(name, ':')) + return strdup(name); - if (!name || !strcmp(name, dflt)) - return strdup(dflt); + full = malloc(strlen("default:CARD=") + strlen(name) + 1); + sprintf(full, "default:CARD=%s", name); - // If we find a colon, we assume it is a real ALSA cardname - if (strchr(name, ':')) - return strdup(name); - - full = malloc(strlen("default:CARD=") + strlen(name) + 1); - sprintf(full, "default:CARD=%s", name); - - return full; + return full; } /* Translate a card index to a ALSA cardname @@ -100,11 +98,11 @@ char *translate_cardname(char *name) */ char *translate_cardidx(int idx) { - char name[32]; + char name[32]; - sprintf(name, "hw:%d", idx); + sprintf(name, "hw:%d", idx); - return strdup(name); + return strdup(name); } /******************************************/ @@ -115,49 +113,50 @@ static PyTypeObject ALSAPCMType; static PyObject *ALSAAudioError; static PyObject * -alsacard_list(PyObject *self, PyObject *args) { - int rc; - int card = -1; - snd_ctl_card_info_t *info; - snd_ctl_t *handle; - PyObject *result = NULL; - - if (!PyArg_ParseTuple(args,":cards")) - return NULL; +alsacard_list(PyObject *self, PyObject *args) +{ + int rc; + int card = -1; + snd_ctl_card_info_t *info; + snd_ctl_t *handle; + PyObject *result = NULL; - snd_ctl_card_info_alloca(&info); - result = PyList_New(0); + if (!PyArg_ParseTuple(args,":cards")) + return NULL; + + snd_ctl_card_info_alloca(&info); + result = PyList_New(0); + + for (rc = snd_card_next(&card); !rc && (card >= 0); + rc = snd_card_next(&card)) + { + char name[32]; + int err; + + /* One would be tempted to think that snd_card_get_name returns a name + that is actually meaningful for any further operations. + + Not in ALSA land. Here we need the id, not the name */ - for (rc = snd_card_next(&card); !rc && (card >= 0); - rc = snd_card_next(&card)) - { - char name[32]; - int err; - - /* One would be tempted to think that snd_card_get_name returns a name - that is actually meaningful for any further operations. - - Not in ALSA land. Here we need the id, not the name */ - - sprintf(name, "hw:%d", card); - if ((err = snd_ctl_open(&handle, name, 0)) < 0) { - PyErr_SetString(ALSAAudioError,snd_strerror(err)); - return NULL; + sprintf(name, "hw:%d", card); + if ((err = snd_ctl_open(&handle, name, 0)) < 0) { + PyErr_SetString(ALSAAudioError,snd_strerror(err)); + return NULL; + } + if ((err = snd_ctl_card_info(handle, info)) < 0) { + PyErr_SetString(ALSAAudioError,snd_strerror(err)); + snd_ctl_close(handle); + Py_DECREF(result); + return NULL; + } + + PyList_Append(result, + PyUnicode_FromString(snd_ctl_card_info_get_id(info))); + + snd_ctl_close(handle); } - if ((err = snd_ctl_card_info(handle, info)) < 0) { - PyErr_SetString(ALSAAudioError,snd_strerror(err)); - snd_ctl_close(handle); - Py_DECREF(result); - return NULL; - } - - PyList_Append(result, - PyUnicode_FromString(snd_ctl_card_info_get_id(info))); - - snd_ctl_close(handle); - } - - return result; + + return result; } PyDoc_STRVAR(cards_doc, @@ -165,130 +164,136 @@ PyDoc_STRVAR(cards_doc, \n\ List the available card ids."); -static int alsapcm_setup(alsapcm_t *self) { - int res,dir; - unsigned int val; - snd_pcm_format_t fmt; - snd_pcm_uframes_t frames; - snd_pcm_hw_params_t *hwparams; +static int alsapcm_setup(alsapcm_t *self) +{ + int res,dir; + unsigned int val; + snd_pcm_format_t fmt; + snd_pcm_uframes_t frames; + snd_pcm_hw_params_t *hwparams; + + /* Allocate a hwparam structure on the stack, + and fill it in with configuration space */ + snd_pcm_hw_params_alloca(&hwparams); + res = snd_pcm_hw_params_any(self->handle, hwparams); + if (res < 0) + return res; + + /* Fill it in with default values. */ + snd_pcm_hw_params_any(self->handle, hwparams); + snd_pcm_hw_params_set_access(self->handle, hwparams, + SND_PCM_ACCESS_RW_INTERLEAVED); + snd_pcm_hw_params_set_format(self->handle, hwparams, self->format); + snd_pcm_hw_params_set_channels(self->handle, hwparams, self->channels); + dir = 0; + snd_pcm_hw_params_set_rate(self->handle, hwparams, self->rate, dir); + snd_pcm_hw_params_set_period_size(self->handle, hwparams, + self->periodsize, dir); + snd_pcm_hw_params_set_periods(self->handle, hwparams, 4, 0); + + /* Write it to the device */ + res = snd_pcm_hw_params(self->handle, hwparams); + if (res) return res; + + /* Query current settings. These may differ from the requested values, + which should therefore be sync'ed with actual values */ + snd_pcm_hw_params_current(self->handle, hwparams); - /* Allocate a hwparam structure on the stack, - and fill it in with configuration space */ - snd_pcm_hw_params_alloca(&hwparams); - res = snd_pcm_hw_params_any(self->handle, hwparams); - if (res < 0) + snd_pcm_hw_params_get_format(hwparams, &fmt); self->format = fmt; + snd_pcm_hw_params_get_channels(hwparams, &val); self->channels = val; + snd_pcm_hw_params_get_rate(hwparams, &val, &dir); self->rate = val; + snd_pcm_hw_params_get_period_size(hwparams, &frames, &dir); + self->periodsize = (int) frames; + + self->framesize = self->channels * snd_pcm_hw_params_get_sbits(hwparams)/8; + return res; - - /* Fill it in with default values. */ - snd_pcm_hw_params_any(self->handle, hwparams); - snd_pcm_hw_params_set_access(self->handle, hwparams, - SND_PCM_ACCESS_RW_INTERLEAVED); - snd_pcm_hw_params_set_format(self->handle, hwparams, self->format); - snd_pcm_hw_params_set_channels(self->handle, hwparams, self->channels); - dir = 0; - snd_pcm_hw_params_set_rate(self->handle, hwparams, self->rate, dir); - snd_pcm_hw_params_set_period_size(self->handle, hwparams, self->periodsize, - dir); - snd_pcm_hw_params_set_periods(self->handle, hwparams, 4, 0); - - /* Write it to the device */ - res = snd_pcm_hw_params(self->handle, hwparams); - if (res) return res; - - /* Query current settings. These may differ from the requested values, - which should therefore be sync'ed with actual values */ - snd_pcm_hw_params_current(self->handle, hwparams); - - snd_pcm_hw_params_get_format(hwparams, &fmt); self->format = fmt; - snd_pcm_hw_params_get_channels(hwparams, &val); self->channels = val; - snd_pcm_hw_params_get_rate(hwparams, &val, &dir); self->rate = val; - snd_pcm_hw_params_get_period_size(hwparams, &frames, &dir); - self->periodsize = (int) frames; - - self->framesize = self->channels * snd_pcm_hw_params_get_sbits(hwparams)/8; - - return res; } static PyObject * -alsapcm_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - int res; - alsapcm_t *self; - int pcmtype = SND_PCM_STREAM_PLAYBACK; - int pcmmode = 0; - char *kw[] = { "type", "mode", "card", NULL }; - char *cardname = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iiz", kw, - &pcmtype, &pcmmode, &cardname)) - return NULL; - - if (!(self = (alsapcm_t *)PyObject_New(alsapcm_t, &ALSAPCMType))) - return NULL; - - if (pcmtype != SND_PCM_STREAM_PLAYBACK && pcmtype != SND_PCM_STREAM_CAPTURE) - { - PyErr_SetString(ALSAAudioError, "PCM type must be PCM_PLAYBACK (0) " - "or PCM_CAPTURE (1)"); - return NULL; - } - if (pcmmode < 0 || pcmmode > SND_PCM_ASYNC) { - PyErr_SetString(ALSAAudioError, "Invalid PCM mode"); - return NULL; - } - self->handle = 0; - self->pcmtype = pcmtype; - self->pcmmode = pcmmode; - self->cardname = translate_cardname(cardname); - self->channels = 2; - self->rate = 44100; - self->format = SND_PCM_FORMAT_S16_LE; - self->periodsize = 32; - - res = snd_pcm_open(&(self->handle), self->cardname, self->pcmtype, - self->pcmmode); - - if (res >= 0) - res = alsapcm_setup(self); - - if (res < 0) { - if (self->handle) { - snd_pcm_close(self->handle); - self->handle = 0; +alsapcm_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + int res; + alsapcm_t *self; + int pcmtype = SND_PCM_STREAM_PLAYBACK; + int pcmmode = 0; + char *kw[] = { "type", "mode", "card", NULL }; + char *cardname = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iiz", kw, + &pcmtype, &pcmmode, &cardname)) + return NULL; + + if (!(self = (alsapcm_t *)PyObject_New(alsapcm_t, &ALSAPCMType))) + return NULL; + + if (pcmtype != SND_PCM_STREAM_PLAYBACK && + pcmtype != SND_PCM_STREAM_CAPTURE) + { + PyErr_SetString(ALSAAudioError, "PCM type must be PCM_PLAYBACK (0) " + "or PCM_CAPTURE (1)"); + return NULL; } - PyErr_SetString(ALSAAudioError, snd_strerror(res)); - return NULL; - } - return (PyObject *)self; + if (pcmmode < 0 || pcmmode > SND_PCM_ASYNC) { + PyErr_SetString(ALSAAudioError, "Invalid PCM mode"); + return NULL; + } + self->handle = 0; + self->pcmtype = pcmtype; + self->pcmmode = pcmmode; + self->cardname = translate_cardname(cardname); + self->channels = 2; + self->rate = 44100; + self->format = SND_PCM_FORMAT_S16_LE; + self->periodsize = 32; + + res = snd_pcm_open(&(self->handle), self->cardname, self->pcmtype, + self->pcmmode); + + if (res >= 0) + res = alsapcm_setup(self); + + if (res < 0) + { + if (self->handle) + { + snd_pcm_close(self->handle); + self->handle = 0; + } + PyErr_SetString(ALSAAudioError, snd_strerror(res)); + return NULL; + } + return (PyObject *)self; } static void alsapcm_dealloc(alsapcm_t *self) { - if (self->handle) { - snd_pcm_drain(self->handle); - snd_pcm_close(self->handle); - } - free(self->cardname); - PyObject_Del(self); + if (self->handle) { + snd_pcm_drain(self->handle); + snd_pcm_close(self->handle); + } + free(self->cardname); + PyObject_Del(self); } static PyObject * alsapcm_close(alsapcm_t *self, PyObject *args) { - if (!PyArg_ParseTuple(args,":close")) - return NULL; - - if (self->handle) { - Py_BEGIN_ALLOW_THREADS - snd_pcm_drain(self->handle); - snd_pcm_close(self->handle); - Py_END_ALLOW_THREADS - - self->handle = 0; - } - - Py_INCREF(Py_None); - return Py_None; + if (!PyArg_ParseTuple(args,":close")) + return NULL; + + if (self->handle) + { + Py_BEGIN_ALLOW_THREADS + snd_pcm_drain(self->handle); + snd_pcm_close(self->handle); + Py_END_ALLOW_THREADS + + self->handle = 0; + } + + Py_INCREF(Py_None); + return Py_None; } PyDoc_STRVAR(pcm_close_doc, @@ -297,115 +302,117 @@ PyDoc_STRVAR(pcm_close_doc, Close a PCM device."); static PyObject * -alsapcm_dumpinfo(alsapcm_t *self, PyObject *args) { - unsigned int val,val2; - snd_pcm_format_t fmt; - int dir; - snd_pcm_uframes_t frames; - snd_pcm_hw_params_t *hwparams; - snd_pcm_hw_params_alloca(&hwparams); - snd_pcm_hw_params_current(self->handle,hwparams); - - if (!PyArg_ParseTuple(args,":dumpinfo")) - return NULL; - - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } - - printf("PCM handle name = '%s'\n", snd_pcm_name(self->handle)); - printf("PCM state = %s\n", snd_pcm_state_name(snd_pcm_state(self->handle))); - - snd_pcm_hw_params_get_access(hwparams, (snd_pcm_access_t *) &val); - printf("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)val)); - - snd_pcm_hw_params_get_format(hwparams, &fmt); - printf("format = '%s' (%s)\n", - snd_pcm_format_name(fmt), - snd_pcm_format_description(fmt)); - - snd_pcm_hw_params_get_subformat(hwparams, (snd_pcm_subformat_t *)&val); - printf("subformat = '%s' (%s)\n", - snd_pcm_subformat_name((snd_pcm_subformat_t)val), - snd_pcm_subformat_description((snd_pcm_subformat_t)val)); - - snd_pcm_hw_params_get_channels(hwparams, &val); - printf("channels = %d\n", val); - - snd_pcm_hw_params_get_rate(hwparams, &val, &dir); - printf("rate = %d bps\n", val); - - snd_pcm_hw_params_get_period_time(hwparams, &val, &dir); - printf("period time = %d us\n", val); - - snd_pcm_hw_params_get_period_size(hwparams, &frames, &dir); - printf("period size = %d frames\n", (int)frames); - - snd_pcm_hw_params_get_buffer_time(hwparams, &val, &dir); - printf("buffer time = %d us\n", val); - - snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t *) &val); - printf("buffer size = %d frames\n", val); - - snd_pcm_hw_params_get_periods(hwparams, &val, &dir); - printf("periods per buffer = %d frames\n", val); - - snd_pcm_hw_params_get_rate_numden(hwparams, &val, &val2); - printf("exact rate = %d/%d bps\n", val, val2); - - val = snd_pcm_hw_params_get_sbits(hwparams); - printf("significant bits = %d\n", val); - - snd_pcm_hw_params_get_period_time(hwparams, &val, &dir); - printf("period time = %d us\n", val); - - val = snd_pcm_hw_params_is_batch(hwparams); - printf("is batch = %d\n", val); - - val = snd_pcm_hw_params_is_block_transfer(hwparams); - printf("is block transfer = %d\n", val); - - val = snd_pcm_hw_params_is_double(hwparams); - printf("is double = %d\n", val); - - val = snd_pcm_hw_params_is_half_duplex(hwparams); - printf("is half duplex = %d\n", val); - - val = snd_pcm_hw_params_is_joint_duplex(hwparams); - printf("is joint duplex = %d\n", val); - - val = snd_pcm_hw_params_can_overrange(hwparams); - printf("can overrange = %d\n", val); - - val = snd_pcm_hw_params_can_mmap_sample_resolution(hwparams); - printf("can mmap = %d\n", val); - - val = snd_pcm_hw_params_can_pause(hwparams); - printf("can pause = %d\n", val); - - val = snd_pcm_hw_params_can_resume(hwparams); - printf("can resume = %d\n", val); - - val = snd_pcm_hw_params_can_sync_start(hwparams); - printf("can sync start = %d\n", val); - - Py_INCREF(Py_None); - return Py_None; +alsapcm_dumpinfo(alsapcm_t *self, PyObject *args) +{ + unsigned int val,val2; + snd_pcm_format_t fmt; + int dir; + snd_pcm_uframes_t frames; + snd_pcm_hw_params_t *hwparams; + snd_pcm_hw_params_alloca(&hwparams); + snd_pcm_hw_params_current(self->handle,hwparams); + if (!PyArg_ParseTuple(args,":dumpinfo")) + return NULL; + + if (!self->handle) { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } + + printf("PCM handle name = '%s'\n", snd_pcm_name(self->handle)); + printf("PCM state = %s\n", + snd_pcm_state_name(snd_pcm_state(self->handle))); + + snd_pcm_hw_params_get_access(hwparams, (snd_pcm_access_t *) &val); + printf("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)val)); + + snd_pcm_hw_params_get_format(hwparams, &fmt); + printf("format = '%s' (%s)\n", + snd_pcm_format_name(fmt), + snd_pcm_format_description(fmt)); + + snd_pcm_hw_params_get_subformat(hwparams, (snd_pcm_subformat_t *)&val); + printf("subformat = '%s' (%s)\n", + snd_pcm_subformat_name((snd_pcm_subformat_t)val), + snd_pcm_subformat_description((snd_pcm_subformat_t)val)); + + snd_pcm_hw_params_get_channels(hwparams, &val); + printf("channels = %d\n", val); + + snd_pcm_hw_params_get_rate(hwparams, &val, &dir); + printf("rate = %d bps\n", val); + + snd_pcm_hw_params_get_period_time(hwparams, &val, &dir); + printf("period time = %d us\n", val); + + snd_pcm_hw_params_get_period_size(hwparams, &frames, &dir); + printf("period size = %d frames\n", (int)frames); + + snd_pcm_hw_params_get_buffer_time(hwparams, &val, &dir); + printf("buffer time = %d us\n", val); + + snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t *) &val); + printf("buffer size = %d frames\n", val); + + snd_pcm_hw_params_get_periods(hwparams, &val, &dir); + printf("periods per buffer = %d frames\n", val); + + snd_pcm_hw_params_get_rate_numden(hwparams, &val, &val2); + printf("exact rate = %d/%d bps\n", val, val2); + + val = snd_pcm_hw_params_get_sbits(hwparams); + printf("significant bits = %d\n", val); + + snd_pcm_hw_params_get_period_time(hwparams, &val, &dir); + printf("period time = %d us\n", val); + + val = snd_pcm_hw_params_is_batch(hwparams); + printf("is batch = %d\n", val); + + val = snd_pcm_hw_params_is_block_transfer(hwparams); + printf("is block transfer = %d\n", val); + + val = snd_pcm_hw_params_is_double(hwparams); + printf("is double = %d\n", val); + + val = snd_pcm_hw_params_is_half_duplex(hwparams); + printf("is half duplex = %d\n", val); + + val = snd_pcm_hw_params_is_joint_duplex(hwparams); + printf("is joint duplex = %d\n", val); + + val = snd_pcm_hw_params_can_overrange(hwparams); + printf("can overrange = %d\n", val); + + val = snd_pcm_hw_params_can_mmap_sample_resolution(hwparams); + printf("can mmap = %d\n", val); + + val = snd_pcm_hw_params_can_pause(hwparams); + printf("can pause = %d\n", val); + + val = snd_pcm_hw_params_can_resume(hwparams); + printf("can resume = %d\n", val); + + val = snd_pcm_hw_params_can_sync_start(hwparams); + printf("can sync start = %d\n", val); + + Py_INCREF(Py_None); + return Py_None; } static PyObject * -alsapcm_pcmtype(alsapcm_t *self, PyObject *args) { - if (!PyArg_ParseTuple(args,":pcmtype")) - return NULL; +alsapcm_pcmtype(alsapcm_t *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args,":pcmtype")) + return NULL; - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } + if (!self->handle) { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } - return PyLong_FromLong(self->pcmtype); + return PyLong_FromLong(self->pcmtype); } PyDoc_STRVAR(pcmtype_doc, @@ -415,16 +422,17 @@ Returns either PCM_CAPTURE or PCM_PLAYBACK."); static PyObject * -alsapcm_pcmmode(alsapcm_t *self, PyObject *args) { - if (!PyArg_ParseTuple(args,":pcmmode")) - return NULL; +alsapcm_pcmmode(alsapcm_t *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args,":pcmmode")) + return NULL; - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } + if (!self->handle) { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } - return PyLong_FromLong(self->pcmmode); + return PyLong_FromLong(self->pcmmode); } PyDoc_STRVAR(pcmmode_doc, @@ -437,16 +445,17 @@ Returns the mode of the PCM object. One of:\n\ static PyObject * -alsapcm_cardname(alsapcm_t *self, PyObject *args) { - if (!PyArg_ParseTuple(args,":cardname")) - return NULL; +alsapcm_cardname(alsapcm_t *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args,":cardname")) + return NULL; - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } + if (!self->handle) { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } - return PyUnicode_FromString(self->cardname); + return PyUnicode_FromString(self->cardname); } PyDoc_STRVAR(cardname_doc, @@ -456,24 +465,26 @@ Returns the name of the sound card used by this PCM object."); static PyObject * -alsapcm_setchannels(alsapcm_t *self, PyObject *args) { - int channels; - int res; - if (!PyArg_ParseTuple(args,"i:setchannels",&channels)) - return NULL; +alsapcm_setchannels(alsapcm_t *self, PyObject *args) +{ + int channels; + int res; + if (!PyArg_ParseTuple(args,"i:setchannels",&channels)) + return NULL; - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } + if (!self->handle) { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } - self->channels = channels; - res = alsapcm_setup(self); - if (res < 0) { - PyErr_SetString(ALSAAudioError, snd_strerror(res)); - return NULL; - } - return PyLong_FromLong(self->channels); + self->channels = channels; + res = alsapcm_setup(self); + if (res < 0) + { + PyErr_SetString(ALSAAudioError, snd_strerror(res)); + return NULL; + } + return PyLong_FromLong(self->channels); } PyDoc_STRVAR(setchannels_doc, @@ -486,24 +497,27 @@ Few sound cards support more than 2 channels."); static PyObject * -alsapcm_setrate(alsapcm_t *self, PyObject *args) { - int rate; - int res; - if (!PyArg_ParseTuple(args,"i:setrate",&rate)) - return NULL; +alsapcm_setrate(alsapcm_t *self, PyObject *args) +{ + int rate; + int res; + if (!PyArg_ParseTuple(args,"i:setrate",&rate)) + return NULL; - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } - self->rate = rate; - res = alsapcm_setup(self); - if (res < 0) { - PyErr_SetString(ALSAAudioError, snd_strerror(res)); - return NULL; - } - return PyLong_FromLong(self->rate); + self->rate = rate; + res = alsapcm_setup(self); + if (res < 0) + { + PyErr_SetString(ALSAAudioError, snd_strerror(res)); + return NULL; + } + return PyLong_FromLong(self->rate); } PyDoc_STRVAR(setrate_doc, @@ -514,49 +528,55 @@ Set the sample rate in Hz for the device. Typical values are\n\ static PyObject * -alsapcm_setformat(alsapcm_t *self, PyObject *args) { - int format; - int res; - if (!PyArg_ParseTuple(args,"i:setformat",&format)) - return NULL; +alsapcm_setformat(alsapcm_t *self, PyObject *args) +{ + int format; + int res; + if (!PyArg_ParseTuple(args,"i:setformat",&format)) + return NULL; - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } - self->format = format; - res = alsapcm_setup(self); - if (res < 0) { - PyErr_SetString(ALSAAudioError, snd_strerror(res)); - return NULL; - } - return PyLong_FromLong(self->format); + self->format = format; + res = alsapcm_setup(self); + if (res < 0) + { + PyErr_SetString(ALSAAudioError, snd_strerror(res)); + return NULL; + } + return PyLong_FromLong(self->format); } PyDoc_STRVAR(setformat_doc, "setformat(rate)\n"); - static PyObject * -alsapcm_setperiodsize(alsapcm_t *self, PyObject *args) { - int periodsize; - int res; - if (!PyArg_ParseTuple(args,"i:setperiodsize",&periodsize)) - return NULL; +alsapcm_setperiodsize(alsapcm_t *self, PyObject *args) +{ + int periodsize; + int res; - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } + if (!PyArg_ParseTuple(args,"i:setperiodsize",&periodsize)) + return NULL; - self->periodsize = periodsize; - res = alsapcm_setup(self); - if (res < 0) { - PyErr_SetString(ALSAAudioError, snd_strerror(res)); - return NULL; - } - return PyLong_FromLong(self->periodsize); + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } + + self->periodsize = periodsize; + res = alsapcm_setup(self); + if (res < 0) + { + PyErr_SetString(ALSAAudioError, snd_strerror(res)); + return NULL; + } + return PyLong_FromLong(self->periodsize); } PyDoc_STRVAR(setperiodsize_doc, @@ -568,52 +588,56 @@ frames (unless the device is in PCM_NONBLOCK mode, in which case it\n\ may return nothing at all)."); static PyObject * -alsapcm_read(alsapcm_t *self, PyObject *args) { - int res; - char buffer[8000]; +alsapcm_read(alsapcm_t *self, PyObject *args) +{ + int res; + char buffer[8000]; - if (self->framesize * self->periodsize > 8000) { - PyErr_SetString(ALSAAudioError,"Capture data too large. " - "Try decreasing period size"); - return NULL; - } - - if (!PyArg_ParseTuple(args,":read")) - return NULL; - - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } - - if (self->pcmtype != SND_PCM_STREAM_CAPTURE) { - PyErr_SetString(ALSAAudioError,"Cannot read from playback PCM"); - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - res = snd_pcm_readi(self->handle, buffer, self->periodsize); - if (res == -EPIPE) { - /* EPIPE means overrun */ - snd_pcm_prepare(self->handle); - } - Py_END_ALLOW_THREADS - - if (res != -EPIPE) - { - if (res == -EAGAIN) { - res = 0; + if (self->framesize * self->periodsize > 8000) { + PyErr_SetString(ALSAAudioError,"Capture data too large. " + "Try decreasing period size"); + return NULL; } - else if (res < 0) { - PyErr_SetString(ALSAAudioError, snd_strerror(res)); - return NULL; - } + + if (!PyArg_ParseTuple(args,":read")) + return NULL; + + if (!self->handle) { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; } + + if (self->pcmtype != SND_PCM_STREAM_CAPTURE) + { + PyErr_SetString(ALSAAudioError,"Cannot read from playback PCM"); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + res = snd_pcm_readi(self->handle, buffer, self->periodsize); + if (res == -EPIPE) + { + /* EPIPE means overrun */ + snd_pcm_prepare(self->handle); + } + Py_END_ALLOW_THREADS + + if (res != -EPIPE) + { + if (res == -EAGAIN) + { + res = 0; + } + else if (res < 0) { + PyErr_SetString(ALSAAudioError, snd_strerror(res)); + return NULL; + } + } #if PY_MAJOR_VERSION < 3 - return Py_BuildValue("is#", res, buffer, res*self->framesize); + return Py_BuildValue("is#", res, buffer, res*self->framesize); #else - return Py_BuildValue("iy#", res, buffer, res*self->framesize); + return Py_BuildValue("iy#", res, buffer, res*self->framesize); #endif } @@ -630,53 +654,56 @@ In PCM_NONBLOCK mode, the call will not block, but will return (0,'')\n\ if no new period has become available since the last call to read."); -static PyObject *alsapcm_write(alsapcm_t *self, PyObject *args) { - - int res; - int datalen; - char *data; - +static PyObject *alsapcm_write(alsapcm_t *self, PyObject *args) +{ + int res; + int datalen; + char *data; + #if PY_MAJOR_VERSION < 3 - if (!PyArg_ParseTuple(args,"s#:write",&data,&datalen)) - return NULL; + if (!PyArg_ParseTuple(args,"s#:write",&data,&datalen)) + return NULL; #else - Py_buffer buf; + Py_buffer buf; - if (!PyArg_ParseTuple(args,"y*:write",&buf)) - return NULL; + if (!PyArg_ParseTuple(args,"y*:write",&buf)) + return NULL; - data = buf.buf; - datalen = buf.len; + data = buf.buf; + datalen = buf.len; #endif - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } - if (datalen % self->framesize) { - PyErr_SetString(ALSAAudioError, - "Data size must be a multiple of framesize"); - return NULL; - } + if (datalen % self->framesize) + { + PyErr_SetString(ALSAAudioError, + "Data size must be a multiple of framesize"); + return NULL; + } - Py_BEGIN_ALLOW_THREADS - res = snd_pcm_writei(self->handle, data, datalen/self->framesize); - if (res == -EPIPE) { - /* EPIPE means underrun */ - res = snd_pcm_recover(self->handle, res, 1); - if (res >= 0) - res = snd_pcm_writei(self->handle, data, datalen/self->framesize); - } - Py_END_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS + res = snd_pcm_writei(self->handle, data, datalen/self->framesize); + if (res == -EPIPE) + { + /* EPIPE means underrun */ + res = snd_pcm_recover(self->handle, res, 1); + if (res >= 0) + res = snd_pcm_writei(self->handle, data, datalen/self->framesize); + } + Py_END_ALLOW_THREADS - if (res == -EAGAIN) { - return PyLong_FromLong(0); - } - else if (res < 0) { - PyErr_SetString(ALSAAudioError,snd_strerror(res)); - return NULL; - } + if (res == -EAGAIN) + return PyLong_FromLong(0); + else if (res < 0) + { + PyErr_SetString(ALSAAudioError,snd_strerror(res)); + return NULL; + } return PyLong_FromLong(res); } @@ -698,26 +725,28 @@ value of zero, if the buffer is full. In this case, the data should be\n\ written at a later time."); -static PyObject *alsapcm_pause(alsapcm_t *self, PyObject *args) { - int enabled=1, res; +static PyObject *alsapcm_pause(alsapcm_t *self, PyObject *args) +{ + int enabled=1, res; - if (!PyArg_ParseTuple(args,"|i:pause",&enabled)) - return NULL; + if (!PyArg_ParseTuple(args,"|i:pause",&enabled)) + return NULL; - if (!self->handle) { - PyErr_SetString(ALSAAudioError, "PCM device is closed"); - return NULL; - } + if (!self->handle) { + PyErr_SetString(ALSAAudioError, "PCM device is closed"); + return NULL; + } - Py_BEGIN_ALLOW_THREADS - res = snd_pcm_pause(self->handle, enabled); - Py_END_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS + res = snd_pcm_pause(self->handle, enabled); + Py_END_ALLOW_THREADS - if (res < 0) { - PyErr_SetString(ALSAAudioError,snd_strerror(res)); - return NULL; - } - return PyLong_FromLong(res); + if (res < 0) + { + PyErr_SetString(ALSAAudioError,snd_strerror(res)); + return NULL; + } + return PyLong_FromLong(res); } PyDoc_STRVAR(pause_doc, @@ -730,74 +759,74 @@ playback/capture is resumed."); /* ALSA PCM Object Bureaucracy */ static PyMethodDef alsapcm_methods[] = { - {"pcmtype", (PyCFunction)alsapcm_pcmtype, METH_VARARGS, pcmtype_doc}, - {"pcmmode", (PyCFunction)alsapcm_pcmmode, METH_VARARGS, pcmmode_doc}, - {"cardname", (PyCFunction)alsapcm_cardname, METH_VARARGS, cardname_doc}, - {"setchannels", (PyCFunction)alsapcm_setchannels, METH_VARARGS, - setchannels_doc }, - {"setrate", (PyCFunction)alsapcm_setrate, METH_VARARGS, setrate_doc}, - {"setformat", (PyCFunction)alsapcm_setformat, METH_VARARGS, setformat_doc}, - {"setperiodsize", (PyCFunction)alsapcm_setperiodsize, METH_VARARGS, - setperiodsize_doc}, - {"dumpinfo", (PyCFunction)alsapcm_dumpinfo, METH_VARARGS}, - {"read", (PyCFunction)alsapcm_read, METH_VARARGS, read_doc}, - {"write", (PyCFunction)alsapcm_write, METH_VARARGS, write_doc}, - {"pause", (PyCFunction)alsapcm_pause, METH_VARARGS, pause_doc}, - {"close", (PyCFunction)alsapcm_close, METH_VARARGS, pcm_close_doc}, - {NULL, NULL} + {"pcmtype", (PyCFunction)alsapcm_pcmtype, METH_VARARGS, pcmtype_doc}, + {"pcmmode", (PyCFunction)alsapcm_pcmmode, METH_VARARGS, pcmmode_doc}, + {"cardname", (PyCFunction)alsapcm_cardname, METH_VARARGS, cardname_doc}, + {"setchannels", (PyCFunction)alsapcm_setchannels, METH_VARARGS, + setchannels_doc }, + {"setrate", (PyCFunction)alsapcm_setrate, METH_VARARGS, setrate_doc}, + {"setformat", (PyCFunction)alsapcm_setformat, METH_VARARGS, setformat_doc}, + {"setperiodsize", (PyCFunction)alsapcm_setperiodsize, METH_VARARGS, + setperiodsize_doc}, + {"dumpinfo", (PyCFunction)alsapcm_dumpinfo, METH_VARARGS}, + {"read", (PyCFunction)alsapcm_read, METH_VARARGS, read_doc}, + {"write", (PyCFunction)alsapcm_write, METH_VARARGS, write_doc}, + {"pause", (PyCFunction)alsapcm_pause, METH_VARARGS, pause_doc}, + {"close", (PyCFunction)alsapcm_close, METH_VARARGS, pcm_close_doc}, + {NULL, NULL} }; #if PY_VERSION_HEX < 0x02020000 static PyObject * alsapcm_getattr(alsapcm_t *self, char *name) { - return Py_FindMethod(alsapcm_methods, (PyObject *)self, name); + return Py_FindMethod(alsapcm_methods, (PyObject *)self, name); } #endif static PyTypeObject ALSAPCMType = { #if PY_MAJOR_VERSION < 3 - PyObject_HEAD_INIT(&PyType_Type) - 0, /* ob_size */ + PyObject_HEAD_INIT(&PyType_Type) + 0, /* ob_size */ #else - PyVarObject_HEAD_INIT(&PyType_Type, 0) + PyVarObject_HEAD_INIT(&PyType_Type, 0) #endif - "alsaaudio.PCM", /* tp_name */ - sizeof(alsapcm_t), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor) alsapcm_dealloc, /* tp_dealloc */ - 0, /* print */ + "alsaaudio.PCM", /* tp_name */ + sizeof(alsapcm_t), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor) alsapcm_dealloc, /* tp_dealloc */ + 0, /* print */ #if PY_VERSION_HEX < 0x02020000 - (getattrfunc)alsapcm_getattr, /* tp_getattr */ + (getattrfunc)alsapcm_getattr, /* tp_getattr */ #else - 0, /* tp_getattr */ + 0, /* tp_getattr */ #endif - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ #if PY_VERSION_HEX >= 0x02020000 - PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericGetAttr, /* tp_getattro */ #else - 0, /* tp_getattro */ + 0, /* tp_getattro */ #endif - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - "ALSA PCM device.", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - alsapcm_methods, /* tp_methods */ - 0, /* tp_members */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "ALSA PCM device.", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + alsapcm_methods, /* tp_methods */ + 0, /* tp_members */ }; @@ -825,53 +854,56 @@ static PyTypeObject ALSAMixerType; #define MIXER_CHANNEL_ALL -1 int -alsamixer_gethandle(char *cardname, snd_mixer_t **handle) { - int err; - if ((err = snd_mixer_open(handle, 0)) < 0) return err; - if ((err = snd_mixer_attach(*handle, cardname)) < 0) return err; - if ((err = snd_mixer_selem_register(*handle, NULL, NULL)) < 0) return err; - if ((err = snd_mixer_load(*handle)) < 0) return err; - - return 0; +alsamixer_gethandle(char *cardname, snd_mixer_t **handle) +{ + int err; + if ((err = snd_mixer_open(handle, 0)) < 0) return err; + if ((err = snd_mixer_attach(*handle, cardname)) < 0) return err; + if ((err = snd_mixer_selem_register(*handle, NULL, NULL)) < 0) return err; + if ((err = snd_mixer_load(*handle)) < 0) return err; + + return 0; } static PyObject * -alsamixer_list(PyObject *self, PyObject *args) { - snd_mixer_t *handle; - snd_mixer_selem_id_t *sid; - snd_mixer_elem_t *elem; - int err; - int cardidx = 0; - char cardname[32]; - PyObject *result; - - if (!PyArg_ParseTuple(args,"|i:mixers",&cardidx)) - return NULL; +alsamixer_list(PyObject *self, PyObject *args) +{ + snd_mixer_t *handle; + snd_mixer_selem_id_t *sid; + snd_mixer_elem_t *elem; + int err; + int cardidx = 0; + char cardname[32]; + PyObject *result; - sprintf(cardname, "hw:%d", cardidx); + if (!PyArg_ParseTuple(args,"|i:mixers",&cardidx)) + return NULL; + + sprintf(cardname, "hw:%d", cardidx); - snd_mixer_selem_id_alloca(&sid); - err = alsamixer_gethandle(cardname, &handle); - if (err < 0) { - PyErr_SetString(ALSAAudioError,snd_strerror(err)); + snd_mixer_selem_id_alloca(&sid); + err = alsamixer_gethandle(cardname, &handle); + if (err < 0) + { + PyErr_SetString(ALSAAudioError,snd_strerror(err)); + snd_mixer_close(handle); + return NULL; + } + + result = PyList_New(0); + + for (elem = snd_mixer_first_elem(handle); elem; + elem = snd_mixer_elem_next(elem)) + { + PyObject *mixer; + snd_mixer_selem_get_id(elem, sid); + mixer = PyUnicode_FromString(snd_mixer_selem_id_get_name(sid)); + PyList_Append(result,mixer); + Py_DECREF(mixer); + } snd_mixer_close(handle); - return NULL; - } - result = PyList_New(0); - - for (elem = snd_mixer_first_elem(handle); elem; - elem = snd_mixer_elem_next(elem)) - { - PyObject *mixer; - snd_mixer_selem_get_id(elem, sid); - mixer = PyUnicode_FromString(snd_mixer_selem_id_get_name(sid)); - PyList_Append(result,mixer); - Py_DECREF(mixer); - } - snd_mixer_close(handle); - - return result; + return result; } PyDoc_STRVAR(mixers_doc, @@ -883,146 +915,163 @@ have more than one sound card). Omit to use the default sound card."); static snd_mixer_elem_t * -alsamixer_find_elem(snd_mixer_t *handle, char *control, int id) { - snd_mixer_selem_id_t *sid; +alsamixer_find_elem(snd_mixer_t *handle, char *control, int id) +{ + snd_mixer_selem_id_t *sid; - snd_mixer_selem_id_alloca(&sid); - snd_mixer_selem_id_set_index(sid, id); - snd_mixer_selem_id_set_name(sid, control); - return snd_mixer_find_selem(handle, sid); + snd_mixer_selem_id_alloca(&sid); + snd_mixer_selem_id_set_index(sid, id); + snd_mixer_selem_id_set_name(sid, control); + return snd_mixer_find_selem(handle, sid); } static PyObject * -alsamixer_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - alsamixer_t *self; - int err; - int cardindex = 0; - char *control = "Master"; - int id = 0; - snd_mixer_elem_t *elem; - int channel; - char *kw[] = { "control", "id", "cardindex", NULL }; +alsamixer_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + alsamixer_t *self; + int err; + int cardindex = 0; + char *control = "Master"; + int id = 0; + snd_mixer_elem_t *elem; + int channel; + char *kw[] = { "control", "id", "cardindex", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sii", kw, + &control, &id, &cardindex)) + return NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sii", kw, - &control, &id, &cardindex)) - return NULL; + if (!(self = (alsamixer_t *)PyObject_New(alsamixer_t, &ALSAMixerType))) + return NULL; - if (!(self = (alsamixer_t *)PyObject_New(alsamixer_t, &ALSAMixerType))) - return NULL; + self->handle = 0; + self->cardname = translate_cardidx(cardindex); - self->handle = 0; - self->cardname = translate_cardidx(cardindex); - - err = alsamixer_gethandle(self->cardname, &self->handle); - if (err<0) { - PyErr_SetString(ALSAAudioError,snd_strerror(err)); - free(self->cardname); - return NULL; - } - - self->controlname = strdup(control); - self->controlid = id; - - elem = alsamixer_find_elem(self->handle,control,id); - if (!elem) { - char errtext[128]; - sprintf(errtext,"Unable to find mixer control '%s',%i",self->controlname, - self->controlid); - snd_mixer_close(self->handle); - PyErr_SetString(ALSAAudioError,errtext); - return NULL; - } - /* Determine mixer capabilities */ - self->volume_cap = self->switch_cap = 0; - if (snd_mixer_selem_has_common_volume(elem)) { - self->volume_cap |= MIXER_CAP_VOLUME; - if (snd_mixer_selem_has_playback_volume_joined(elem)) - self->volume_cap |= MIXER_CAP_VOLUME_JOINED; - } - else { - if (snd_mixer_selem_has_playback_volume(elem)) { - self->volume_cap |= MIXER_CAP_PVOLUME; - if (snd_mixer_selem_has_playback_volume_joined(elem)) - self->volume_cap |= MIXER_CAP_PVOLUME_JOINED; + err = alsamixer_gethandle(self->cardname, &self->handle); + if (err<0) + { + PyErr_SetString(ALSAAudioError,snd_strerror(err)); + free(self->cardname); + return NULL; } - if (snd_mixer_selem_has_capture_volume(elem)) { - self->volume_cap |= MIXER_CAP_CVOLUME; - if (snd_mixer_selem_has_capture_volume_joined(elem)) - self->volume_cap |= MIXER_CAP_CVOLUME_JOINED; - } - } - if (snd_mixer_selem_has_common_switch(elem)) { - self->switch_cap |= MIXER_CAP_SWITCH; - if (snd_mixer_selem_has_playback_switch_joined(elem)) - self->switch_cap |= MIXER_CAP_SWITCH_JOINED; - } - else { - if (snd_mixer_selem_has_playback_switch(elem)) { - self->switch_cap |= MIXER_CAP_PSWITCH; - if (snd_mixer_selem_has_playback_switch_joined(elem)) - self->switch_cap |= MIXER_CAP_PSWITCH_JOINED; + self->controlname = strdup(control); + self->controlid = id; + + elem = alsamixer_find_elem(self->handle,control,id); + if (!elem) + { + char errtext[128]; + sprintf(errtext,"Unable to find mixer control '%s',%i", + self->controlname, + self->controlid); + snd_mixer_close(self->handle); + PyErr_SetString(ALSAAudioError,errtext); + return NULL; } - if (snd_mixer_selem_has_capture_switch(elem)) { - self->switch_cap |= MIXER_CAP_CSWITCH; - if (snd_mixer_selem_has_capture_switch_joined(elem)) - self->switch_cap |= MIXER_CAP_CSWITCH_JOINED; - if (snd_mixer_selem_has_capture_switch_exclusive(elem)) - self->switch_cap |= MIXER_CAP_CSWITCH_EXCLUSIVE; + /* Determine mixer capabilities */ + self->volume_cap = self->switch_cap = 0; + if (snd_mixer_selem_has_common_volume(elem)) + { + self->volume_cap |= MIXER_CAP_VOLUME; + if (snd_mixer_selem_has_playback_volume_joined(elem)) + self->volume_cap |= MIXER_CAP_VOLUME_JOINED; } - } - self->pchannels = 0; - if (self->volume_cap | MIXER_CAP_PVOLUME || - self->switch_cap | MIXER_CAP_PSWITCH) { - if (snd_mixer_selem_is_playback_mono(elem)) self->pchannels = 1; - else { - for (channel=0; channel <= SND_MIXER_SCHN_LAST; channel++) { - if (snd_mixer_selem_has_playback_channel(elem, channel)) - self->pchannels++; - else break; - } + else + { + if (snd_mixer_selem_has_playback_volume(elem)) + { + self->volume_cap |= MIXER_CAP_PVOLUME; + if (snd_mixer_selem_has_playback_volume_joined(elem)) + self->volume_cap |= MIXER_CAP_PVOLUME_JOINED; + } + if (snd_mixer_selem_has_capture_volume(elem)) + { + self->volume_cap |= MIXER_CAP_CVOLUME; + if (snd_mixer_selem_has_capture_volume_joined(elem)) + self->volume_cap |= MIXER_CAP_CVOLUME_JOINED; + } } - } - self->cchannels = 0; - if (self->volume_cap | MIXER_CAP_CVOLUME || - self->switch_cap | MIXER_CAP_CSWITCH) { - if (snd_mixer_selem_is_capture_mono(elem)) self->cchannels = 1; - else { - for (channel=0; channel <= SND_MIXER_SCHN_LAST; channel++) { - if (snd_mixer_selem_has_capture_channel(elem, channel)) - self->cchannels++; - else break; - } + + if (snd_mixer_selem_has_common_switch(elem)) + { + self->switch_cap |= MIXER_CAP_SWITCH; + if (snd_mixer_selem_has_playback_switch_joined(elem)) + self->switch_cap |= MIXER_CAP_SWITCH_JOINED; } - } - snd_mixer_selem_get_playback_volume_range(elem, &self->pmin, &self->pmax); - snd_mixer_selem_get_capture_volume_range(elem, &self->cmin, &self->cmax); - return (PyObject *)self; + else + { + if (snd_mixer_selem_has_playback_switch(elem)) { + self->switch_cap |= MIXER_CAP_PSWITCH; + if (snd_mixer_selem_has_playback_switch_joined(elem)) + self->switch_cap |= MIXER_CAP_PSWITCH_JOINED; + } + if (snd_mixer_selem_has_capture_switch(elem)) { + self->switch_cap |= MIXER_CAP_CSWITCH; + if (snd_mixer_selem_has_capture_switch_joined(elem)) + self->switch_cap |= MIXER_CAP_CSWITCH_JOINED; + if (snd_mixer_selem_has_capture_switch_exclusive(elem)) + self->switch_cap |= MIXER_CAP_CSWITCH_EXCLUSIVE; + } + } + self->pchannels = 0; + if (self->volume_cap | MIXER_CAP_PVOLUME || + self->switch_cap | MIXER_CAP_PSWITCH) + { + if (snd_mixer_selem_is_playback_mono(elem)) self->pchannels = 1; + else { + for (channel=0; channel <= SND_MIXER_SCHN_LAST; channel++) { + if (snd_mixer_selem_has_playback_channel(elem, channel)) + self->pchannels++; + else break; + } + } + } + self->cchannels = 0; + if (self->volume_cap | MIXER_CAP_CVOLUME || + self->switch_cap | MIXER_CAP_CSWITCH) + { + if (snd_mixer_selem_is_capture_mono(elem)) + self->cchannels = 1; + else + { + for (channel=0; channel <= SND_MIXER_SCHN_LAST; channel++) { + if (snd_mixer_selem_has_capture_channel(elem, channel)) + self->cchannels++; + else break; + } + } + } + snd_mixer_selem_get_playback_volume_range(elem, &self->pmin, &self->pmax); + snd_mixer_selem_get_capture_volume_range(elem, &self->cmin, &self->cmax); + + return (PyObject *)self; } -static void alsamixer_dealloc(alsamixer_t *self) { - if (self->handle) { - snd_mixer_close(self->handle); - free(self->cardname); - free(self->controlname); - self->handle = 0; - } - PyObject_Del(self); +static void alsamixer_dealloc(alsamixer_t *self) +{ + if (self->handle) { + snd_mixer_close(self->handle); + free(self->cardname); + free(self->controlname); + self->handle = 0; + } + PyObject_Del(self); } static PyObject * alsamixer_close(alsamixer_t *self, PyObject *args) { - if (!PyArg_ParseTuple(args,":close")) - return NULL; - - snd_mixer_close(self->handle); - free(self->cardname); - free(self->controlname); - self->handle = 0; - - Py_INCREF(Py_None); - return Py_None; + if (!PyArg_ParseTuple(args,":close")) + return NULL; + + snd_mixer_close(self->handle); + free(self->cardname); + free(self->controlname); + self->handle = 0; + + Py_INCREF(Py_None); + return Py_None; } PyDoc_STRVAR(mixer_close_doc, @@ -1033,16 +1082,16 @@ Close a Mixer."); static PyObject * alsamixer_cardname(alsamixer_t *self, PyObject *args) { - if (!PyArg_ParseTuple(args,":cardname")) - return NULL; - - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - return PyUnicode_FromString(self->cardname); + if (!PyArg_ParseTuple(args,":cardname")) + return NULL; + + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; + } + + return PyUnicode_FromString(self->cardname); } PyDoc_STRVAR(mixer_cardname_doc, @@ -1053,16 +1102,16 @@ Returns the name of the sound card used by this Mixer object."); static PyObject * alsamixer_mixer(alsamixer_t *self, PyObject *args) { - if (!PyArg_ParseTuple(args,":mixer")) - return NULL; - - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - return PyUnicode_FromString(self->controlname); + if (!PyArg_ParseTuple(args,":mixer")) + return NULL; + + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; + } + + return PyUnicode_FromString(self->controlname); } PyDoc_STRVAR(mixer_doc, @@ -1073,17 +1122,18 @@ for example 'Master' or 'PCM'"); static PyObject * -alsamixer_mixerid(alsamixer_t *self, PyObject *args) { - if (!PyArg_ParseTuple(args,":mixerid")) - return NULL; - - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - return PyLong_FromLong(self->controlid); +alsamixer_mixerid(alsamixer_t *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args,":mixerid")) + return NULL; + + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; + } + + return PyLong_FromLong(self->controlid); } PyDoc_STRVAR(mixerid_doc, @@ -1093,24 +1143,32 @@ Returns the ID of the ALSA mixer controlled by this object."); static PyObject * -alsamixer_volumecap(alsamixer_t *self, PyObject *args) { - PyObject *result; - if (!PyArg_ParseTuple(args,":volumecap")) return NULL; - result = PyList_New(0); - if (self->volume_cap&MIXER_CAP_VOLUME) - PyList_Append(result,PyUnicode_FromString("Volume")); - if (self->volume_cap&MIXER_CAP_VOLUME_JOINED) - PyList_Append(result,PyUnicode_FromString("Joined Volume")); - if (self->volume_cap&MIXER_CAP_PVOLUME) - PyList_Append(result,PyUnicode_FromString("Playback Volume")); - if (self->volume_cap&MIXER_CAP_PVOLUME_JOINED) - PyList_Append(result,PyUnicode_FromString("Joined Playback Volume")); - if (self->volume_cap&MIXER_CAP_CVOLUME) - PyList_Append(result,PyUnicode_FromString("Capture Volume")); - if (self->volume_cap&MIXER_CAP_CVOLUME_JOINED) - PyList_Append(result,PyUnicode_FromString("Joined Capture Volume")); - - return result; +alsamixer_volumecap(alsamixer_t *self, PyObject *args) +{ + PyObject *result; + if (!PyArg_ParseTuple(args,":volumecap")) return NULL; + + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; + } + + result = PyList_New(0); + if (self->volume_cap&MIXER_CAP_VOLUME) + PyList_Append(result,PyUnicode_FromString("Volume")); + if (self->volume_cap&MIXER_CAP_VOLUME_JOINED) + PyList_Append(result,PyUnicode_FromString("Joined Volume")); + if (self->volume_cap&MIXER_CAP_PVOLUME) + PyList_Append(result,PyUnicode_FromString("Playback Volume")); + if (self->volume_cap&MIXER_CAP_PVOLUME_JOINED) + PyList_Append(result,PyUnicode_FromString("Joined Playback Volume")); + if (self->volume_cap&MIXER_CAP_CVOLUME) + PyList_Append(result,PyUnicode_FromString("Capture Volume")); + if (self->volume_cap&MIXER_CAP_CVOLUME_JOINED) + PyList_Append(result,PyUnicode_FromString("Joined Capture Volume")); + + return result; } PyDoc_STRVAR(volumecap_doc, @@ -1127,25 +1185,35 @@ Possible values in this list are:\n\ static PyObject * -alsamixer_switchcap(alsamixer_t *self, PyObject *args) { - PyObject *result; - if (!PyArg_ParseTuple(args,":switchcap")) return NULL; - result = PyList_New(0); - if (self->volume_cap&MIXER_CAP_SWITCH) - PyList_Append(result,PyUnicode_FromString("Mute")); - if (self->volume_cap&MIXER_CAP_SWITCH_JOINED) - PyList_Append(result,PyUnicode_FromString("Joined Mute")); - if (self->volume_cap&MIXER_CAP_PSWITCH) - PyList_Append(result,PyUnicode_FromString("Playback Mute")); - if (self->volume_cap&MIXER_CAP_PSWITCH_JOINED) - PyList_Append(result,PyUnicode_FromString("Joined Playback Mute")); - if (self->volume_cap&MIXER_CAP_CSWITCH) - PyList_Append(result,PyUnicode_FromString("Capture Mute")); - if (self->volume_cap&MIXER_CAP_CSWITCH_JOINED) - PyList_Append(result,PyUnicode_FromString("Joined Capture Mute")); - if (self->volume_cap&MIXER_CAP_CSWITCH_EXCLUSIVE) - PyList_Append(result,PyUnicode_FromString("Capture Exclusive")); - return result; +alsamixer_switchcap(alsamixer_t *self, PyObject *args) +{ + PyObject *result; + if (!PyArg_ParseTuple(args,":switchcap")) + return NULL; + + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; + } + + result = PyList_New(0); + if (self->volume_cap&MIXER_CAP_SWITCH) + PyList_Append(result,PyUnicode_FromString("Mute")); + if (self->volume_cap&MIXER_CAP_SWITCH_JOINED) + PyList_Append(result,PyUnicode_FromString("Joined Mute")); + if (self->volume_cap&MIXER_CAP_PSWITCH) + PyList_Append(result,PyUnicode_FromString("Playback Mute")); + if (self->volume_cap&MIXER_CAP_PSWITCH_JOINED) + PyList_Append(result,PyUnicode_FromString("Joined Playback Mute")); + if (self->volume_cap&MIXER_CAP_CSWITCH) + PyList_Append(result,PyUnicode_FromString("Capture Mute")); + if (self->volume_cap&MIXER_CAP_CSWITCH_JOINED) + PyList_Append(result,PyUnicode_FromString("Joined Capture Mute")); + if (self->volume_cap&MIXER_CAP_CSWITCH_EXCLUSIVE) + PyList_Append(result,PyUnicode_FromString("Capture Exclusive")); + + return result; } PyDoc_STRVAR(switchcap_doc, @@ -1163,76 +1231,95 @@ Possible values in this list are:\n\ - 'Capture Exclusive'\n"); -static int alsamixer_getpercentage(long min, long max, long value) { - /* Convert from number in range to percentage */ - int range = max - min; - int tmp; +static int alsamixer_getpercentage(long min, long max, long value) +{ + /* Convert from number in range to percentage */ + int range = max - min; + int tmp; - if (range == 0) return 0; - value -= min; - tmp = rint((double)value/(double)range * 100); - return tmp; + if (range == 0) + return 0; + + value -= min; + tmp = rint((double)value/(double)range * 100); + return tmp; } -static long alsamixer_getphysvolume(long min, long max, int percentage) { - /* Convert from percentage to number in range */ - int range = max - min; - int tmp; +static long alsamixer_getphysvolume(long min, long max, int percentage) +{ + /* Convert from percentage to number in range */ + int range = max - min; + int tmp; + + if (range == 0) + return 0; - if (range == 0) return 0; - tmp = rint((double)range * ((double)percentage*.01)) + min; - return tmp; + tmp = rint((double)range * ((double)percentage*.01)) + min; + return tmp; } static PyObject * -alsamixer_getvolume(alsamixer_t *self, PyObject *args) { - snd_mixer_elem_t *elem; - int direction; - int channel; - long ival; - char *dirstr = 0; - PyObject *result; - - if (!PyArg_ParseTuple(args,"|s:getvolume",&dirstr)) - return NULL; - - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); - - if (!dirstr) { - if (self->pchannels) direction = 0; - else direction = 1; - } - else if (strcasecmp(dirstr,"playback")==0) direction = 0; - else if (strcasecmp(dirstr,"capture")==0) direction = 1; - else { - PyErr_SetString(ALSAAudioError,"Invalid direction argument for mixer"); - return NULL; - } - result = PyList_New(0); - for (channel = 0; channel <= SND_MIXER_SCHN_LAST; channel++) { - if (direction == 0 && snd_mixer_selem_has_playback_channel(elem, channel)) +alsamixer_getvolume(alsamixer_t *self, PyObject *args) +{ + snd_mixer_elem_t *elem; + int direction; + int channel; + long ival; + char *dirstr = 0; + PyObject *result; + + if (!PyArg_ParseTuple(args,"|s:getvolume",&dirstr)) + return NULL; + + if (!self->handle) { - snd_mixer_selem_get_playback_volume(elem, channel, &ival); - PyList_Append( - result, PyLong_FromLong(alsamixer_getpercentage(self->pmin, - self->pmax, ival))); + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; } - else if (direction == 1 - && snd_mixer_selem_has_capture_channel(elem, channel) - && snd_mixer_selem_has_capture_volume(elem)) { - snd_mixer_selem_get_capture_volume(elem, channel, &ival); - PyList_Append( - result, PyLong_FromLong(alsamixer_getpercentage(self->cmin, - self->cmax, ival))); + + elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); + + if (!dirstr) + { + if (self->pchannels) + direction = 0; + else + direction = 1; } - } - return result; + else if (strcasecmp(dirstr,"playback")==0) + direction = 0; + else if (strcasecmp(dirstr,"capture")==0) + direction = 1; + else + { + PyErr_SetString(ALSAAudioError,"Invalid direction argument for mixer"); + return NULL; + } + + result = PyList_New(0); + + for (channel = 0; channel <= SND_MIXER_SCHN_LAST; channel++) { + if (direction == 0 && + snd_mixer_selem_has_playback_channel(elem, channel)) + { + snd_mixer_selem_get_playback_volume(elem, channel, &ival); + PyList_Append( + result, PyLong_FromLong(alsamixer_getpercentage(self->pmin, + self->pmax, + ival))); + } + else if (direction == 1 + && snd_mixer_selem_has_capture_channel(elem, channel) + && snd_mixer_selem_has_capture_volume(elem)) { + snd_mixer_selem_get_capture_volume(elem, channel, &ival); + PyList_Append( + result, PyLong_FromLong(alsamixer_getpercentage(self->cmin, + self->cmax, + ival))); + } + } + + return result; } PyDoc_STRVAR(getvolume_doc, @@ -1248,54 +1335,64 @@ if the mixer has this capability, otherwise 'capture'"); static PyObject * -alsamixer_getrange(alsamixer_t *self, PyObject *args) { - snd_mixer_elem_t *elem; - int direction; - char *dirstr = 0; +alsamixer_getrange(alsamixer_t *self, PyObject *args) +{ + snd_mixer_elem_t *elem; + int direction; + char *dirstr = 0; + + if (!PyArg_ParseTuple(args,"|s:getrange",&dirstr)) + return NULL; - if (!PyArg_ParseTuple(args,"|s:getrange",&dirstr)) - return NULL; - - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); - - if (!dirstr) { - if (self->pchannels) direction = 0; - else direction = 1; - } - else if (strcasecmp(dirstr,"playback")==0) direction = 0; - else if (strcasecmp(dirstr,"capture")==0) direction = 1; - else { - PyErr_SetString(ALSAAudioError,"Invalid argument for direction"); - return NULL; - } - if (direction == 0) { - if (snd_mixer_selem_has_playback_channel(elem, 0)) { - return Py_BuildValue("[ii]", self->pmin, self->pmax); + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; } - - PyErr_SetString(ALSAAudioError, "Mixer has no playback channel"); - return NULL; - } - else if (direction == 1) { - if (snd_mixer_selem_has_capture_channel(elem, 0) - && snd_mixer_selem_has_capture_volume(elem)) { - return Py_BuildValue("[ii]", self->cmin, self->cmax); + + elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); + + if (!dirstr) + { + if (self->pchannels) + direction = 0; + else + direction = 1; } + else if (strcasecmp(dirstr,"playback")==0) + direction = 0; + else if (strcasecmp(dirstr,"capture")==0) + direction = 1; + else + { + PyErr_SetString(ALSAAudioError,"Invalid argument for direction"); + return NULL; + } + if (direction == 0) + { + if (snd_mixer_selem_has_playback_channel(elem, 0)) + { + return Py_BuildValue("[ii]", self->pmin, self->pmax); + } - PyErr_SetString(ALSAAudioError, "Mixer has no capture channel " - "or capture volume"); - return NULL; - } + PyErr_SetString(ALSAAudioError, "Mixer has no playback channel"); + return NULL; + } + else if (direction == 1) + { + if (snd_mixer_selem_has_capture_channel(elem, 0) + && snd_mixer_selem_has_capture_volume(elem)) { + return Py_BuildValue("[ii]", self->cmin, self->cmax); + } + + PyErr_SetString(ALSAAudioError, "Mixer has no capture channel " + "or capture volume"); + return NULL; + } - // Unreached statement - PyErr_SetString(ALSAAudioError,"Huh?"); - return NULL; + // Unreached statement + PyErr_SetString(ALSAAudioError,"Huh?"); + return NULL; } PyDoc_STRVAR(getrange_doc, @@ -1310,75 +1407,80 @@ if the mixer has this capability, otherwise 'capture'"); static PyObject * -alsamixer_getenum(alsamixer_t *self, PyObject *args) { - snd_mixer_elem_t *elem; - PyObject *elems; - int i, count, rc; - unsigned int index; - char name[32]; +alsamixer_getenum(alsamixer_t *self, PyObject *args) +{ + snd_mixer_elem_t *elem; + PyObject *elems; + int i, count, rc; + unsigned int index; + char name[32]; + PyObject *result; - PyObject *result; - if (!PyArg_ParseTuple(args, ":getenum")) - return NULL; + if (!PyArg_ParseTuple(args, ":getenum")) + return NULL; - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); - if (!snd_mixer_selem_is_enumerated(elem)) { - // Not an enumerated control, return an empty tuple - return PyTuple_New(0); - } - - count = snd_mixer_selem_get_enum_items(elem); - if (count < 0) { - PyErr_SetString(ALSAAudioError, snd_strerror(count)); - return NULL; - } - - result = PyTuple_New(2); - if (!result) - return NULL; - - rc = snd_mixer_selem_get_enum_item(elem, 0, &index); - if(rc) { - PyErr_SetString(ALSAAudioError, snd_strerror(rc)); - return NULL; - } - rc = snd_mixer_selem_get_enum_item_name(elem, index, sizeof(name)-1, name); - if (rc) { - Py_DECREF(result); - PyErr_SetString(ALSAAudioError, snd_strerror(rc)); - return NULL; - } - - PyTuple_SetItem(result, 0, PyUnicode_FromString(name)); - - elems = PyList_New(count); - if (!elems) - { - Py_DECREF(result); - return NULL; - } - - for (i = 0; i < count; ++i) { - rc = snd_mixer_selem_get_enum_item_name(elem, i, sizeof(name)-1, name); - if (rc) { - Py_DECREF(elems); - Py_DECREF(result); - PyErr_SetString(ALSAAudioError, snd_strerror(rc)); - return NULL; + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; + } + + elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); + if (!snd_mixer_selem_is_enumerated(elem)) { + // Not an enumerated control, return an empty tuple + return PyTuple_New(0); + } + + count = snd_mixer_selem_get_enum_items(elem); + if (count < 0) + { + PyErr_SetString(ALSAAudioError, snd_strerror(count)); + return NULL; } - PyList_SetItem(elems, i, PyUnicode_FromString(name)); - } + result = PyTuple_New(2); + if (!result) + return NULL; + + rc = snd_mixer_selem_get_enum_item(elem, 0, &index); + if(rc) + { + PyErr_SetString(ALSAAudioError, snd_strerror(rc)); + return NULL; + } + rc = snd_mixer_selem_get_enum_item_name(elem, index, sizeof(name)-1, name); + if (rc) + { + Py_DECREF(result); + PyErr_SetString(ALSAAudioError, snd_strerror(rc)); + return NULL; + } + + PyTuple_SetItem(result, 0, PyUnicode_FromString(name)); - PyTuple_SetItem(result, 1, elems); + elems = PyList_New(count); + if (!elems) + { + Py_DECREF(result); + return NULL; + } - return result; + for (i = 0; i < count; ++i) + { + rc = snd_mixer_selem_get_enum_item_name(elem, i, sizeof(name)-1, name); + if (rc) { + Py_DECREF(elems); + Py_DECREF(result); + PyErr_SetString(ALSAAudioError, snd_strerror(rc)); + return NULL; + } + + PyList_SetItem(elems, i, PyUnicode_FromString(name)); + } + + PyTuple_SetItem(result, 1, elems); + + return result; } PyDoc_STRVAR(getenum_doc, @@ -1388,33 +1490,37 @@ Returns a a tuple. The first element is name of the active enumerated item, \n\ the second a list available enumerated items."); static PyObject * -alsamixer_getmute(alsamixer_t *self, PyObject *args) { - snd_mixer_elem_t *elem; - int i; - int ival; - PyObject *result; - if (!PyArg_ParseTuple(args,":getmute")) - return NULL; +alsamixer_getmute(alsamixer_t *self, PyObject *args) +{ + snd_mixer_elem_t *elem; + int i; + int ival; + PyObject *result; + if (!PyArg_ParseTuple(args,":getmute")) + return NULL; - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); - if (!snd_mixer_selem_has_playback_switch(elem)) { - PyErr_SetString(ALSAAudioError,"Mixer has no mute switch"); - return NULL; - } - result = PyList_New(0); - for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) { - if (snd_mixer_selem_has_playback_channel(elem, i)) { - snd_mixer_selem_get_playback_switch(elem, i, &ival); - PyList_Append(result,PyLong_FromLong(!ival)); + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; } - } - return result; + + elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); + if (!snd_mixer_selem_has_playback_switch(elem)) + { + PyErr_SetString(ALSAAudioError,"Mixer has no mute switch"); + return NULL; + } + result = PyList_New(0); + for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) + { + if (snd_mixer_selem_has_playback_channel(elem, i)) + { + snd_mixer_selem_get_playback_switch(elem, i, &ival); + PyList_Append(result,PyLong_FromLong(!ival)); + } + } + return result; } PyDoc_STRVAR(getmute_doc, @@ -1427,33 +1533,37 @@ This method will fail if the mixer has no playback switch capabilities."); static PyObject * -alsamixer_getrec(alsamixer_t *self, PyObject *args) { - snd_mixer_elem_t *elem; - int i; - int ival; - PyObject *result; - if (!PyArg_ParseTuple(args,":getrec")) - return NULL; - - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); - if (!snd_mixer_selem_has_capture_switch(elem)) { - PyErr_SetString(ALSAAudioError,"Mixer has no record switch"); - return NULL; - } - result = PyList_New(0); - for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) { - if (snd_mixer_selem_has_capture_channel(elem, i)) { - snd_mixer_selem_get_capture_switch(elem, i, &ival); - PyList_Append(result,PyLong_FromLong(!ival)); +alsamixer_getrec(alsamixer_t *self, PyObject *args) +{ + snd_mixer_elem_t *elem; + int i; + int ival; + PyObject *result; + if (!PyArg_ParseTuple(args,":getrec")) + return NULL; + + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; } - } - return result; + + elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); + if (!snd_mixer_selem_has_capture_switch(elem)) + { + PyErr_SetString(ALSAAudioError,"Mixer has no record switch"); + return NULL; + } + result = PyList_New(0); + for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) + { + if (snd_mixer_selem_has_capture_channel(elem, i)) + { + snd_mixer_selem_get_capture_switch(elem, i, &ival); + PyList_Append(result,PyLong_FromLong(!ival)); + } + } + return result; } PyDoc_STRVAR(getrec_doc, @@ -1465,65 +1575,81 @@ This method will fail if the mixer has no capture switch capabilities."); static PyObject * -alsamixer_setvolume(alsamixer_t *self, PyObject *args) { - snd_mixer_elem_t *elem; - int direction; - int i; - long volume; - int physvolume; - char *dirstr = 0; - int channel = MIXER_CHANNEL_ALL; - int done = 0; +alsamixer_setvolume(alsamixer_t *self, PyObject *args) +{ + snd_mixer_elem_t *elem; + int direction; + int i; + long volume; + int physvolume; + char *dirstr = 0; + int channel = MIXER_CHANNEL_ALL; + int done = 0; - if (!PyArg_ParseTuple(args,"l|is:setvolume",&volume,&channel,&dirstr)) - return NULL; + if (!PyArg_ParseTuple(args,"l|is:setvolume",&volume,&channel,&dirstr)) + return NULL; - if (volume < 0 || volume > 100) { - PyErr_SetString(ALSAAudioError,"Volume must be between 0 and 100"); - return NULL; - } - - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); - - if (!dirstr) { - if (self->pchannels) direction = 0; - else direction = 1; - } - else if (strcasecmp(dirstr,"playback")==0) direction = 0; - else if (strcasecmp(dirstr,"capture")==0) direction = 1; - else { - PyErr_SetString(ALSAAudioError,"Invalid direction argument. Use " - "'playback' or 'capture'"); - return NULL; - } - for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) { - if (channel == -1 || channel == i) { - if (direction == 0 && snd_mixer_selem_has_playback_channel(elem, i)) { - physvolume = alsamixer_getphysvolume(self->pmin,self->pmax,volume); - snd_mixer_selem_set_playback_volume(elem, i, physvolume); - done++; - } - else if (direction == 1 - && snd_mixer_selem_has_capture_channel(elem, channel) - && snd_mixer_selem_has_capture_volume(elem)) { - physvolume = alsamixer_getphysvolume(self->cmin,self->cmax,volume); - snd_mixer_selem_set_capture_volume(elem, i, physvolume); - done++; - } + if (volume < 0 || volume > 100) + { + PyErr_SetString(ALSAAudioError,"Volume must be between 0 and 100"); + return NULL; } - } - if(!done) { - PyErr_SetString(ALSAAudioError,"No such channel"); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; + + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; + } + + elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); + + if (!dirstr) + { + if (self->pchannels) + direction = 0; + else + direction = 1; + } + else if (strcasecmp(dirstr,"playback")==0) + direction = 0; + else if (strcasecmp(dirstr,"capture")==0) + direction = 1; + else + { + PyErr_SetString(ALSAAudioError,"Invalid direction argument. Use " + "'playback' or 'capture'"); + return NULL; + } + for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) + { + if (channel == -1 || channel == i) + { + if (direction == 0 && + snd_mixer_selem_has_playback_channel(elem, i)) { + physvolume = alsamixer_getphysvolume(self->pmin, + self->pmax, volume); + snd_mixer_selem_set_playback_volume(elem, i, physvolume); + done++; + } + else if (direction == 1 + && snd_mixer_selem_has_capture_channel(elem, channel) + && snd_mixer_selem_has_capture_volume(elem)) + { + physvolume = alsamixer_getphysvolume(self->cmin,self->cmax, + volume); + snd_mixer_selem_set_capture_volume(elem, i, physvolume); + done++; + } + } + } + if(!done) + { + PyErr_SetString(ALSAAudioError,"No such channel"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; } PyDoc_STRVAR(setvolume_doc, @@ -1543,40 +1669,47 @@ The default is 'playback' if the mixer has this capability, otherwise\n\ static PyObject * -alsamixer_setmute(alsamixer_t *self, PyObject *args) { - snd_mixer_elem_t *elem; - int i; - int mute = 0; - int done = 0; - int channel = MIXER_CHANNEL_ALL; - if (!PyArg_ParseTuple(args,"i|i:setmute",&mute,&channel)) - return NULL; +alsamixer_setmute(alsamixer_t *self, PyObject *args) +{ + snd_mixer_elem_t *elem; + int i; + int mute = 0; + int done = 0; + int channel = MIXER_CHANNEL_ALL; + if (!PyArg_ParseTuple(args,"i|i:setmute",&mute,&channel)) + return NULL; - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); - if (!snd_mixer_selem_has_playback_switch(elem)) { - PyErr_SetString(ALSAAudioError,"Mixer has no mute switch"); - return NULL; - } - for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) { - if (channel == MIXER_CHANNEL_ALL || channel == i) { - if (snd_mixer_selem_has_playback_channel(elem, i)) { - snd_mixer_selem_set_playback_switch(elem, i, !mute); - done++; - } + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; } - } - if (!done) { - PyErr_SetString(ALSAAudioError,"Invalid channel number"); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; + + elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); + if (!snd_mixer_selem_has_playback_switch(elem)) + { + PyErr_SetString(ALSAAudioError,"Mixer has no mute switch"); + return NULL; + } + for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) + { + if (channel == MIXER_CHANNEL_ALL || channel == i) + { + if (snd_mixer_selem_has_playback_channel(elem, i)) + { + snd_mixer_selem_set_playback_switch(elem, i, !mute); + done++; + } + } + } + if (!done) + { + PyErr_SetString(ALSAAudioError,"Invalid channel number"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; } PyDoc_STRVAR(setmute_doc, @@ -1591,41 +1724,48 @@ This method will fail if the mixer has no playback mute capabilities"); static PyObject * -alsamixer_setrec(alsamixer_t *self, PyObject *args) { - snd_mixer_elem_t *elem; - int i; - int rec = 0; - int done = 0; - int channel = MIXER_CHANNEL_ALL; - - if (!PyArg_ParseTuple(args,"i|i:setrec",&rec,&channel)) - return NULL; - - if (!self->handle) - { - PyErr_SetString(ALSAAudioError, "Mixer is closed"); - return NULL; - } - - elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); - if (!snd_mixer_selem_has_capture_switch(elem)) { - PyErr_SetString(ALSAAudioError,"Mixer has no record switch"); - return NULL; - } - for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) { - if (channel == MIXER_CHANNEL_ALL || channel == i) { - if (snd_mixer_selem_has_capture_channel(elem, i)) { - snd_mixer_selem_set_playback_switch(elem, i, rec); - done++; - } +alsamixer_setrec(alsamixer_t *self, PyObject *args) +{ + snd_mixer_elem_t *elem; + int i; + int rec = 0; + int done = 0; + int channel = MIXER_CHANNEL_ALL; + + if (!PyArg_ParseTuple(args,"i|i:setrec",&rec,&channel)) + return NULL; + + if (!self->handle) + { + PyErr_SetString(ALSAAudioError, "Mixer is closed"); + return NULL; } - } - if (!done) { - PyErr_SetString(ALSAAudioError,"Invalid channel number"); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; + + elem = alsamixer_find_elem(self->handle,self->controlname,self->controlid); + if (!snd_mixer_selem_has_capture_switch(elem)) + { + PyErr_SetString(ALSAAudioError,"Mixer has no record switch"); + return NULL; + } + for (i = 0; i <= SND_MIXER_SCHN_LAST; i++) + { + if (channel == MIXER_CHANNEL_ALL || channel == i) + { + if (snd_mixer_selem_has_capture_channel(elem, i)) + { + snd_mixer_selem_set_playback_switch(elem, i, rec); + done++; + } + } + } + if (!done) + { + PyErr_SetString(ALSAAudioError,"Invalid channel number"); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; } PyDoc_STRVAR(setrec_doc, @@ -1640,75 +1780,80 @@ This method will fail if the mixer has no capture switch capabilities"); static PyMethodDef alsamixer_methods[] = { - {"cardname", (PyCFunction)alsamixer_cardname, METH_VARARGS, - mixer_cardname_doc}, - {"close", (PyCFunction)alsamixer_close, METH_VARARGS, mixer_close_doc}, - {"mixer", (PyCFunction)alsamixer_mixer, METH_VARARGS, mixer_doc}, - {"mixerid", (PyCFunction)alsamixer_mixerid, METH_VARARGS, mixerid_doc}, - {"switchcap", (PyCFunction)alsamixer_switchcap, METH_VARARGS, switchcap_doc}, - {"volumecap", (PyCFunction)alsamixer_volumecap, METH_VARARGS, volumecap_doc}, - {"getvolume", (PyCFunction)alsamixer_getvolume, METH_VARARGS, getvolume_doc}, - {"getrange", (PyCFunction)alsamixer_getrange, METH_VARARGS, getrange_doc}, - {"getenum", (PyCFunction)alsamixer_getenum, METH_VARARGS, getenum_doc}, - {"getmute", (PyCFunction)alsamixer_getmute, METH_VARARGS, getmute_doc}, - {"getrec", (PyCFunction)alsamixer_getrec, METH_VARARGS, getrec_doc}, - {"setvolume", (PyCFunction)alsamixer_setvolume, METH_VARARGS, setvolume_doc}, - {"setmute", (PyCFunction)alsamixer_setmute, METH_VARARGS, setmute_doc}, - {"setrec", (PyCFunction)alsamixer_setrec, METH_VARARGS, setrec_doc}, - {NULL, NULL} + {"cardname", (PyCFunction)alsamixer_cardname, METH_VARARGS, + mixer_cardname_doc}, + {"close", (PyCFunction)alsamixer_close, METH_VARARGS, mixer_close_doc}, + {"mixer", (PyCFunction)alsamixer_mixer, METH_VARARGS, mixer_doc}, + {"mixerid", (PyCFunction)alsamixer_mixerid, METH_VARARGS, mixerid_doc}, + {"switchcap", (PyCFunction)alsamixer_switchcap, METH_VARARGS, + switchcap_doc}, + {"volumecap", (PyCFunction)alsamixer_volumecap, METH_VARARGS, + volumecap_doc}, + {"getvolume", (PyCFunction)alsamixer_getvolume, METH_VARARGS, + getvolume_doc}, + {"getrange", (PyCFunction)alsamixer_getrange, METH_VARARGS, getrange_doc}, + {"getenum", (PyCFunction)alsamixer_getenum, METH_VARARGS, getenum_doc}, + {"getmute", (PyCFunction)alsamixer_getmute, METH_VARARGS, getmute_doc}, + {"getrec", (PyCFunction)alsamixer_getrec, METH_VARARGS, getrec_doc}, + {"setvolume", (PyCFunction)alsamixer_setvolume, METH_VARARGS, + setvolume_doc}, + {"setmute", (PyCFunction)alsamixer_setmute, METH_VARARGS, setmute_doc}, + {"setrec", (PyCFunction)alsamixer_setrec, METH_VARARGS, setrec_doc}, + {NULL, NULL} }; #if PY_VERSION_HEX < 0x02020000 static PyObject * -alsamixer_getattr(alsapcm_t *self, char *name) { - return Py_FindMethod(alsamixer_methods, (PyObject *)self, name); +alsamixer_getattr(alsapcm_t *self, char *name) +{ + return Py_FindMethod(alsamixer_methods, (PyObject *)self, name); } #endif static PyTypeObject ALSAMixerType = { #if PY_MAJOR_VERSION < 3 - PyObject_HEAD_INIT(&PyType_Type) - 0, /* ob_size */ + PyObject_HEAD_INIT(&PyType_Type) + 0, /* ob_size */ #else - PyVarObject_HEAD_INIT(&PyType_Type, 0) + PyVarObject_HEAD_INIT(&PyType_Type, 0) #endif - "alsaaudio.Mixer", /* tp_name */ - sizeof(alsamixer_t), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor) alsamixer_dealloc, /* tp_dealloc */ - 0, /* print */ + "alsaaudio.Mixer", /* tp_name */ + sizeof(alsamixer_t), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor) alsamixer_dealloc, /* tp_dealloc */ + 0, /* print */ #if PY_VERSION_HEX < 0x02020000 - (getattrfunc)alsamixer_getattr, /* tp_getattr */ + (getattrfunc)alsamixer_getattr, /* tp_getattr */ #else - 0, /* tp_getattr */ + 0, /* tp_getattr */ #endif - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ #if PY_VERSION_HEX >= 0x02020000 - PyObject_GenericGetAttr, /* tp_getattro*/ + PyObject_GenericGetAttr, /* tp_getattro*/ #else - 0, /* tp_getattro*/ + 0, /* tp_getattro*/ #endif - 0, /* tp_setattro*/ - 0, /* tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - "ALSA Mixer Control.", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - alsamixer_methods, /* tp_methods */ - 0, /* tp_members */ + 0, /* tp_setattro*/ + 0, /* tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "ALSA Mixer Control.", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + alsamixer_methods, /* tp_methods */ + 0, /* tp_members */ }; @@ -1717,9 +1862,9 @@ static PyTypeObject ALSAMixerType = { /******************************************/ static PyMethodDef alsaaudio_methods[] = { - { "cards", alsacard_list, METH_VARARGS, cards_doc}, - { "mixers", alsamixer_list, METH_VARARGS, mixers_doc}, - { 0, 0 }, + { "cards", alsacard_list, METH_VARARGS, cards_doc}, + { "mixers", alsamixer_list, METH_VARARGS, mixers_doc}, + { 0, 0 }, }; @@ -1729,15 +1874,15 @@ static PyMethodDef alsaaudio_methods[] = { if (PyModule_AddIntConstant(mod, name, (long) value) == -1) return NULL; static struct PyModuleDef alsaaudio_module = { - PyModuleDef_HEAD_INIT, - "alsaaudio", - alsaaudio_module_doc, - -1, - alsaaudio_methods, - 0, /* m_reload */ - 0, /* m_traverse */ - 0, /* m_clear */ - 0, /* m_free */ + PyModuleDef_HEAD_INIT, + "alsaaudio", + alsaaudio_module_doc, + -1, + alsaaudio_methods, + 0, /* m_reload */ + 0, /* m_traverse */ + 0, /* m_clear */ + 0, /* m_free */ }; #else @@ -1753,93 +1898,94 @@ void initalsaaudio(void) PyObject *PyInit_alsaaudio(void) #endif { - PyObject *m; - ALSAPCMType.tp_new = alsapcm_new; - ALSAMixerType.tp_new = alsamixer_new; + PyObject *m; + ALSAPCMType.tp_new = alsapcm_new; + ALSAMixerType.tp_new = alsamixer_new; - PyEval_InitThreads(); + PyEval_InitThreads(); #if PY_MAJOR_VERSION < 3 - m = Py_InitModule3("alsaaudio", alsaaudio_methods, alsaaudio_module_doc); - if (!m) - return; + m = Py_InitModule3("alsaaudio", alsaaudio_methods, alsaaudio_module_doc); + if (!m) + return; #else - m = PyModule_Create(&alsaaudio_module); - if (!m) - return NULL; + m = PyModule_Create(&alsaaudio_module); + if (!m) + return NULL; #endif - ALSAAudioError = PyErr_NewException("alsaaudio.ALSAAudioError", NULL, NULL); - if (!ALSAAudioError) + ALSAAudioError = PyErr_NewException("alsaaudio.ALSAAudioError", NULL, + NULL); + if (!ALSAAudioError) #if PY_MAJOR_VERSION < 3 - return; + return; #else - return NULL; + return NULL; #endif - /* Each call to PyModule_AddObject decrefs it; compensate: */ + /* Each call to PyModule_AddObject decrefs it; compensate: */ - Py_INCREF(&ALSAPCMType); - PyModule_AddObject(m, "PCM", (PyObject *)&ALSAPCMType); + Py_INCREF(&ALSAPCMType); + PyModule_AddObject(m, "PCM", (PyObject *)&ALSAPCMType); - Py_INCREF(&ALSAMixerType); - PyModule_AddObject(m, "Mixer", (PyObject *)&ALSAMixerType); + Py_INCREF(&ALSAMixerType); + PyModule_AddObject(m, "Mixer", (PyObject *)&ALSAMixerType); + + Py_INCREF(ALSAAudioError); + PyModule_AddObject(m, "ALSAAudioError", ALSAAudioError); - Py_INCREF(ALSAAudioError); - PyModule_AddObject(m, "ALSAAudioError", ALSAAudioError); - - _EXPORT_INT(m, "PCM_PLAYBACK",SND_PCM_STREAM_PLAYBACK); - _EXPORT_INT(m, "PCM_CAPTURE",SND_PCM_STREAM_CAPTURE); - - _EXPORT_INT(m, "PCM_NORMAL",0); - _EXPORT_INT(m, "PCM_NONBLOCK",SND_PCM_NONBLOCK); - _EXPORT_INT(m, "PCM_ASYNC",SND_PCM_ASYNC); - - /* PCM Formats */ - _EXPORT_INT(m, "PCM_FORMAT_S8",SND_PCM_FORMAT_S8); - _EXPORT_INT(m, "PCM_FORMAT_U8",SND_PCM_FORMAT_U8); - _EXPORT_INT(m, "PCM_FORMAT_S16_LE",SND_PCM_FORMAT_S16_LE); - _EXPORT_INT(m, "PCM_FORMAT_S16_BE",SND_PCM_FORMAT_S16_BE); - _EXPORT_INT(m, "PCM_FORMAT_U16_LE",SND_PCM_FORMAT_U16_LE); - _EXPORT_INT(m, "PCM_FORMAT_U16_BE",SND_PCM_FORMAT_U16_BE); - _EXPORT_INT(m, "PCM_FORMAT_S24_LE",SND_PCM_FORMAT_S24_LE); - _EXPORT_INT(m, "PCM_FORMAT_S24_BE",SND_PCM_FORMAT_S24_BE); - _EXPORT_INT(m, "PCM_FORMAT_U24_LE",SND_PCM_FORMAT_U24_LE); - _EXPORT_INT(m, "PCM_FORMAT_U24_BE",SND_PCM_FORMAT_U24_BE); - _EXPORT_INT(m, "PCM_FORMAT_S32_LE",SND_PCM_FORMAT_S32_LE); - _EXPORT_INT(m, "PCM_FORMAT_S32_BE",SND_PCM_FORMAT_S32_BE); - _EXPORT_INT(m, "PCM_FORMAT_U32_LE",SND_PCM_FORMAT_U32_LE); - _EXPORT_INT(m, "PCM_FORMAT_U32_BE",SND_PCM_FORMAT_U32_BE); - _EXPORT_INT(m, "PCM_FORMAT_FLOAT_LE",SND_PCM_FORMAT_FLOAT_LE); - _EXPORT_INT(m, "PCM_FORMAT_FLOAT_BE",SND_PCM_FORMAT_FLOAT_BE); - _EXPORT_INT(m, "PCM_FORMAT_FLOAT64_LE",SND_PCM_FORMAT_FLOAT64_LE); - _EXPORT_INT(m, "PCM_FORMAT_FLOAT64_BE",SND_PCM_FORMAT_FLOAT64_BE); - _EXPORT_INT(m, "PCM_FORMAT_MU_LAW",SND_PCM_FORMAT_MU_LAW); - _EXPORT_INT(m, "PCM_FORMAT_A_LAW",SND_PCM_FORMAT_A_LAW); - _EXPORT_INT(m, "PCM_FORMAT_IMA_ADPCM",SND_PCM_FORMAT_IMA_ADPCM); - _EXPORT_INT(m, "PCM_FORMAT_MPEG",SND_PCM_FORMAT_MPEG); - _EXPORT_INT(m, "PCM_FORMAT_GSM",SND_PCM_FORMAT_GSM); - - /* Mixer stuff */ - _EXPORT_INT(m, "MIXER_CHANNEL_ALL", MIXER_CHANNEL_ALL); + _EXPORT_INT(m, "PCM_PLAYBACK",SND_PCM_STREAM_PLAYBACK); + _EXPORT_INT(m, "PCM_CAPTURE",SND_PCM_STREAM_CAPTURE); + + _EXPORT_INT(m, "PCM_NORMAL",0); + _EXPORT_INT(m, "PCM_NONBLOCK",SND_PCM_NONBLOCK); + _EXPORT_INT(m, "PCM_ASYNC",SND_PCM_ASYNC); + /* PCM Formats */ + _EXPORT_INT(m, "PCM_FORMAT_S8",SND_PCM_FORMAT_S8); + _EXPORT_INT(m, "PCM_FORMAT_U8",SND_PCM_FORMAT_U8); + _EXPORT_INT(m, "PCM_FORMAT_S16_LE",SND_PCM_FORMAT_S16_LE); + _EXPORT_INT(m, "PCM_FORMAT_S16_BE",SND_PCM_FORMAT_S16_BE); + _EXPORT_INT(m, "PCM_FORMAT_U16_LE",SND_PCM_FORMAT_U16_LE); + _EXPORT_INT(m, "PCM_FORMAT_U16_BE",SND_PCM_FORMAT_U16_BE); + _EXPORT_INT(m, "PCM_FORMAT_S24_LE",SND_PCM_FORMAT_S24_LE); + _EXPORT_INT(m, "PCM_FORMAT_S24_BE",SND_PCM_FORMAT_S24_BE); + _EXPORT_INT(m, "PCM_FORMAT_U24_LE",SND_PCM_FORMAT_U24_LE); + _EXPORT_INT(m, "PCM_FORMAT_U24_BE",SND_PCM_FORMAT_U24_BE); + _EXPORT_INT(m, "PCM_FORMAT_S32_LE",SND_PCM_FORMAT_S32_LE); + _EXPORT_INT(m, "PCM_FORMAT_S32_BE",SND_PCM_FORMAT_S32_BE); + _EXPORT_INT(m, "PCM_FORMAT_U32_LE",SND_PCM_FORMAT_U32_LE); + _EXPORT_INT(m, "PCM_FORMAT_U32_BE",SND_PCM_FORMAT_U32_BE); + _EXPORT_INT(m, "PCM_FORMAT_FLOAT_LE",SND_PCM_FORMAT_FLOAT_LE); + _EXPORT_INT(m, "PCM_FORMAT_FLOAT_BE",SND_PCM_FORMAT_FLOAT_BE); + _EXPORT_INT(m, "PCM_FORMAT_FLOAT64_LE",SND_PCM_FORMAT_FLOAT64_LE); + _EXPORT_INT(m, "PCM_FORMAT_FLOAT64_BE",SND_PCM_FORMAT_FLOAT64_BE); + _EXPORT_INT(m, "PCM_FORMAT_MU_LAW",SND_PCM_FORMAT_MU_LAW); + _EXPORT_INT(m, "PCM_FORMAT_A_LAW",SND_PCM_FORMAT_A_LAW); + _EXPORT_INT(m, "PCM_FORMAT_IMA_ADPCM",SND_PCM_FORMAT_IMA_ADPCM); + _EXPORT_INT(m, "PCM_FORMAT_MPEG",SND_PCM_FORMAT_MPEG); + _EXPORT_INT(m, "PCM_FORMAT_GSM",SND_PCM_FORMAT_GSM); + + /* Mixer stuff */ + _EXPORT_INT(m, "MIXER_CHANNEL_ALL", MIXER_CHANNEL_ALL); + #if 0 // Omit for now - use case unknown - _EXPORT_INT(m, "MIXER_SCHN_UNKNOWN", SND_MIXER_SCHN_UNKNOWN); - _EXPORT_INT(m, "MIXER_SCHN_FRONT_LEFT", SND_MIXER_SCHN_FRONT_LEFT); - _EXPORT_INT(m, "MIXER_SCHN_FRONT_RIGHT", SND_MIXER_SCHN_FRONT_RIGHT); - _EXPORT_INT(m, "MIXER_SCHN_REAR_LEFT", SND_MIXER_SCHN_REAR_LEFT); - _EXPORT_INT(m, "MIXER_SCHN_REAR_RIGHT", SND_MIXER_SCHN_REAR_RIGHT); - _EXPORT_INT(m, "MIXER_SCHN_FRONT_CENTER", SND_MIXER_SCHN_FRONT_CENTER); - _EXPORT_INT(m, "MIXER_SCHN_WOOFER", SND_MIXER_SCHN_WOOFER); - _EXPORT_INT(m, "MIXER_SCHN_SIDE_LEFT", SND_MIXER_SCHN_SIDE_LEFT); - _EXPORT_INT(m, "MIXER_SCHN_SIDE_RIGHT", SND_MIXER_SCHN_SIDE_RIGHT); - _EXPORT_INT(m, "MIXER_SCHN_REAR_CENTER", SND_MIXER_SCHN_REAR_CENTER); - _EXPORT_INT(m, "MIXER_SCHN_MONO", SND_MIXER_SCHN_MONO); + _EXPORT_INT(m, "MIXER_SCHN_UNKNOWN", SND_MIXER_SCHN_UNKNOWN); + _EXPORT_INT(m, "MIXER_SCHN_FRONT_LEFT", SND_MIXER_SCHN_FRONT_LEFT); + _EXPORT_INT(m, "MIXER_SCHN_FRONT_RIGHT", SND_MIXER_SCHN_FRONT_RIGHT); + _EXPORT_INT(m, "MIXER_SCHN_REAR_LEFT", SND_MIXER_SCHN_REAR_LEFT); + _EXPORT_INT(m, "MIXER_SCHN_REAR_RIGHT", SND_MIXER_SCHN_REAR_RIGHT); + _EXPORT_INT(m, "MIXER_SCHN_FRONT_CENTER", SND_MIXER_SCHN_FRONT_CENTER); + _EXPORT_INT(m, "MIXER_SCHN_WOOFER", SND_MIXER_SCHN_WOOFER); + _EXPORT_INT(m, "MIXER_SCHN_SIDE_LEFT", SND_MIXER_SCHN_SIDE_LEFT); + _EXPORT_INT(m, "MIXER_SCHN_SIDE_RIGHT", SND_MIXER_SCHN_SIDE_RIGHT); + _EXPORT_INT(m, "MIXER_SCHN_REAR_CENTER", SND_MIXER_SCHN_REAR_CENTER); + _EXPORT_INT(m, "MIXER_SCHN_MONO", SND_MIXER_SCHN_MONO); #endif #if PY_MAJOR_VERSION >= 3 - return m; + return m; #endif }