initial commit

This commit is contained in:
josch 2014-06-26 10:32:15 +02:00
commit 84534fdd73
4 changed files with 1046 additions and 0 deletions

399
alsa.pyx Normal file
View file

@ -0,0 +1,399 @@
# do some opaque struct typedefs to make const typedefs possible
cdef extern from "alsa/asoundlib.h":
ctypedef struct snd_mixer_t
ctypedef struct snd_mixer_class_t
ctypedef struct snd_pcm_t
ctypedef struct snd_mixer_elem_t
ctypedef struct snd_mixer_selem_id_t
# define const ptr types as cython doesnt know const
cdef extern from *:
ctypedef char* const_char_ptr "const char*"
ctypedef snd_mixer_selem_id_t* const_snd_mixer_selem_id_t_ptr "const snd_mixer_selem_id_t *"
ctypedef snd_mixer_elem_t* const_snd_mixer_elem_t_ptr "const snd_mixer_elem_t *"
ctypedef snd_mixer_t* const_snd_mixer_t_ptr "const snd_mixer_t *"
cdef extern from "stdlib.h":
ctypedef unsigned long size_t
void *calloc(size_t count, size_t size)
void *malloc(size_t size)
void free(void *ptr)
void *realloc(void *ptr, size_t size)
cdef extern from "alloca.h":
void *alloca(size_t size)
cdef extern from "string.h":
void *memset (void *s, int c, size_t n)
cdef extern from "sys/poll.h":
struct pollfd:
int fd
short int events
cdef extern from "alsa/asoundlib.h":
ctypedef enum snd_mixer_selem_regopt_abstract:
pass
ctypedef enum snd_mixer_elem_type_t:
pass
ctypedef enum snd_mixer_selem_channel_id_t:
pass
struct snd_mixer_selem_regopt:
pass
ctypedef int (*snd_mixer_compare_t)(const_snd_mixer_elem_t_ptr e1, const_snd_mixer_elem_t_ptr e2)
ctypedef int (*snd_mixer_callback_t)(snd_mixer_t *ctl, unsigned int mask, snd_mixer_elem_t *elem)
ctypedef int (*snd_mixer_elem_callback_t)(snd_mixer_elem_t *elem, unsigned int mask)
int snd_mixer_open(snd_mixer_t **mixer, int mode)
int snd_mixer_close(snd_mixer_t *mixer)
snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer)
snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer)
int snd_mixer_handle_events(snd_mixer_t *mixer)
int snd_mixer_attach(snd_mixer_t *mixer, const_char_ptr name)
int snd_mixer_detach(snd_mixer_t *mixer, const_char_ptr name)
int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer)
int snd_mixer_poll_descriptors(snd_mixer_t *mixer, pollfd *pfds, unsigned int space)
int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, pollfd *pfds, unsigned int nfds, unsigned short *revents)
int snd_mixer_load(snd_mixer_t *mixer)
void snd_mixer_free(snd_mixer_t *mixer)
int snd_mixer_wait(snd_mixer_t *mixer, int timeout)
int snd_mixer_set_compare(snd_mixer_t *mixer, snd_mixer_compare_t msort)
void snd_mixer_set_callback(snd_mixer_t *obj, snd_mixer_callback_t val)
void * snd_mixer_get_callback_private(const_snd_mixer_t_ptr obj)
void snd_mixer_set_callback_private(snd_mixer_t *obj, void * val)
unsigned int snd_mixer_get_count(const_snd_mixer_t_ptr obj)
int snd_mixer_class_unregister(snd_mixer_class_t *clss)
snd_mixer_elem_t *snd_mixer_elem_next(snd_mixer_elem_t *elem)
snd_mixer_elem_t *snd_mixer_elem_prev(snd_mixer_elem_t *elem)
void snd_mixer_elem_set_callback(snd_mixer_elem_t *obj, snd_mixer_elem_callback_t val)
void * snd_mixer_elem_get_callback_private(const_snd_mixer_elem_t_ptr obj)
void snd_mixer_elem_set_callback_private(snd_mixer_elem_t *obj, void * val)
snd_mixer_elem_type_t snd_mixer_elem_get_type(const_snd_mixer_elem_t_ptr obj)
int snd_mixer_selem_register(snd_mixer_t *mixer, snd_mixer_selem_regopt *options, snd_mixer_class_t **classp)
void snd_mixer_selem_get_id(snd_mixer_elem_t *element, snd_mixer_selem_id_t *id)
const_char_ptr snd_mixer_selem_get_name(snd_mixer_elem_t *elem)
unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem)
snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer, const_snd_mixer_selem_id_t_ptr id)
int snd_mixer_selem_is_active(snd_mixer_elem_t *elem)
int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel)
int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel)
int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_common_volume(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_volume_joined(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_common_switch(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem)
int snd_mixer_selem_ask_playback_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue)
int snd_mixer_selem_ask_capture_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue)
int snd_mixer_selem_ask_playback_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value)
int snd_mixer_selem_ask_capture_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value)
int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
int snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
int snd_mixer_selem_get_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
int snd_mixer_selem_set_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir)
int snd_mixer_selem_set_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir)
int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value)
int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value)
int snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *elem, long value, int dir)
int snd_mixer_selem_set_capture_dB_all(snd_mixer_elem_t *elem, long value, int dir)
int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value)
int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value)
int snd_mixer_selem_get_playback_volume_range(snd_mixer_elem_t *elem, long *min, long *max)
int snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem, long *min, long *max)
int snd_mixer_selem_set_playback_volume_range(snd_mixer_elem_t *elem, long min, long max)
int snd_mixer_selem_get_capture_volume_range(snd_mixer_elem_t *elem, long *min, long *max)
int snd_mixer_selem_get_capture_dB_range(snd_mixer_elem_t *elem, long *min, long *max)
int snd_mixer_selem_set_capture_volume_range(snd_mixer_elem_t *elem, long min, long max)
int snd_mixer_selem_is_enumerated(snd_mixer_elem_t *elem)
int snd_mixer_selem_is_enum_playback(snd_mixer_elem_t *elem)
int snd_mixer_selem_is_enum_capture(snd_mixer_elem_t *elem)
int snd_mixer_selem_get_enum_items(snd_mixer_elem_t *elem)
int snd_mixer_selem_get_enum_item_name(snd_mixer_elem_t *elem, unsigned int idx, size_t maxlen, char *str)
int snd_mixer_selem_get_enum_item(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int *idxp)
int snd_mixer_selem_set_enum_item(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int idx)
size_t snd_mixer_selem_id_sizeof()
int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr)
void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj)
void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const_snd_mixer_selem_id_t_ptr src)
const_char_ptr snd_mixer_selem_id_get_name(const_snd_mixer_selem_id_t_ptr obj)
unsigned int snd_mixer_selem_id_get_index(const_snd_mixer_selem_id_t_ptr obj)
void snd_mixer_selem_id_set_name(snd_mixer_selem_id_t *obj, const_char_ptr val)
void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val)
cdef struct selem:
snd_mixer_elem_t *elem
selem *next
SANE_CONTROL_COUNT = 16 # assuming a sane value of 16 controls
def rel_to_abs(min, max, value):
return int(value*(max-min)+min)
def abs_to_rel(min, max, value):
return float((value-min))/(max-min)
cdef class Mixer:
cdef snd_mixer_t *handle
cdef snd_mixer_elem_t **selems
_elements = dict()
def __init__(self, card="hw:0"):
cdef int selem_count = 0, selems_size = SANE_CONTROL_COUNT
cdef snd_mixer_elem_t *temp_elem
cdef snd_mixer_elem_t **temp_elems
cdef char name[32]
cdef int enum_items_count, value
cdef int err
cdef long pmin, pmax, cmin, cmax
err = snd_mixer_open(&self.handle, 0)
if err < 0: return
err = snd_mixer_attach(self.handle, card)
if err < 0: return
err = snd_mixer_selem_register(self.handle, NULL, NULL)
if err < 0: return
err = snd_mixer_load(self.handle)
if err < 0: return
self.selems = <snd_mixer_elem_t **>malloc(selems_size*sizeof(snd_mixer_elem_t *))
temp_elem = snd_mixer_first_elem(self.handle)
while temp_elem:
selem_count += 1
if selem_count > selems_size:
# running out of space - realloc double the size
selems_size *= 2
temp_elems = <snd_mixer_elem_t **>realloc(self.selems, selems_size*sizeof(snd_mixer_elem_t *))
if not temp_elems:
raise MemoryError
return
self.selems = temp_elems
self.selems[selem_count-1] = temp_elem
enumeration = None
if snd_mixer_selem_is_enumerated(temp_elem):
enumeration = list()
enum_items_count = snd_mixer_selem_get_enum_items(temp_elem)
for i from 0 <= i < enum_items_count:
snd_mixer_selem_get_enum_item_name(temp_elem, i, sizeof(name)-1, name)
enumeration.append(name)
playback_volume = None
if snd_mixer_selem_has_playback_volume(temp_elem):
snd_mixer_selem_get_playback_volume_range(temp_elem, &pmin, &pmax)
playback_volume = (pmin, pmax)
playback_switch = None
if snd_mixer_selem_has_playback_switch(temp_elem):
playback_switch = True
capture_volume = None
if snd_mixer_selem_has_capture_volume(temp_elem):
snd_mixer_selem_get_capture_volume_range(temp_elem, &cmin, &cmax)
capture_volume = (cmin, cmax)
capture_switch = None
if snd_mixer_selem_has_capture_switch(temp_elem):
capture_switch = True
self._elements[snd_mixer_selem_get_name(temp_elem)] = {
"index": selem_count-1,
"enumeration": enumeration,
"playback_volume": playback_volume,
"playback_switch": playback_switch,
"capture_volume": capture_volume,
"capture_switch": capture_switch
}
temp_elem = snd_mixer_elem_next(temp_elem)
# shrink allocated memory to exact needed size
self.selems = <snd_mixer_elem_t **>realloc(self.selems, selem_count*sizeof(snd_mixer_elem_t *))
def get_enum_items(self, elem):
if elem not in self._elements:
raise KeyError("not a valid control", elem)
return self._elements[elem]["enumeration"]
def get_enum_item(self, elem):
cdef unsigned int idx
cdef snd_mixer_elem_t * selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
elem = self._elements[elem]
if elem["enumeration"] is None:
return
selem = self.selems[elem["index"]]
snd_mixer_selem_get_enum_item(selem, <snd_mixer_selem_channel_id_t>0, &idx)
return elem["enumeration"][idx]
def set_enum_item(self, elem, value):
cdef unsigned int idx
cdef snd_mixer_elem_t * selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
elem = self._elements[elem]
if elem["enumeration"] is None:
return
if value not in elem["enumeration"]:
if value < len(elem["enumeration"]):
idx = value
else:
raise KeyError("not a valid enumeration item", value)
else:
idx = elem["enumeration"].index(value)
selem = self.selems[elem["index"]]
snd_mixer_selem_set_enum_item(selem, <snd_mixer_selem_channel_id_t>0, idx)
def get_playback_volume(self, elem):
cdef long ival
cdef snd_mixer_elem_t * selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
elem = self._elements[elem]
if elem["playback_volume"] is None:
return
min, max = elem["playback_volume"]
selem = self.selems[elem["index"]]
snd_mixer_selem_get_playback_volume(selem, <snd_mixer_selem_channel_id_t>0, &ival)
return abs_to_rel(min, max, ival)
def set_playback_volume(self, elem, value):
cdef snd_mixer_elem_t * selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
if value < 0 or value > 1:
raise ValueError("value out of range [0..1]", value)
elem = self._elements[elem]
if elem["playback_volume"] is None:
return
min, max = elem["playback_volume"]
selem = self.selems[elem["index"]]
ival = rel_to_abs(min, max, value)
snd_mixer_selem_set_playback_volume_all(selem, ival)
def get_capture_volume(self, elem):
cdef long ival
cdef snd_mixer_elem_t * selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
elem = self._elements[elem]
if elem["capture_volume"] is None:
return
min, max = elem["capture_volume"]
selem = self.selems[elem["index"]]
snd_mixer_selem_get_capture_volume(selem, <snd_mixer_selem_channel_id_t>0, &ival)
return abs_to_rel(min, max, ival)
def set_capture_volume(self, elem, value):
cdef snd_mixer_elem_t * selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
if value < 0 or value > 1:
raise ValueError("value out of range [0..1]", value)
elem = self._elements[elem]
if elem["capture_volume"] is None:
return
min, max = elem["capture_volume"]
selem = self.selems[elem["index"]]
ival = rel_to_abs(min, max, value)
snd_mixer_selem_set_capture_volume_all(selem, ival)
def get_playback_switch(self, elem):
cdef int value
cdef snd_mixer_elem_t * selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
elem = self._elements[elem]
if elem["playback_switch"] is None:
return
selem = self.selems[elem["index"]]
snd_mixer_selem_get_playback_switch(selem, <snd_mixer_selem_channel_id_t>0, &value)
return bool(value)
def set_playback_switch(self, elem, value):
cdef snd_mixer_elem_t * selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
elem = self._elements[elem]
if elem["playback_switch"] is None:
return
selem = self.selems[elem["index"]]
value = int(bool(value))
snd_mixer_selem_set_playback_switch_all(selem, value)
def get_capture_switeh(self, elem):
cdef int value
cdef snd_mixer_elem_t * selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
elem = self._elements[elem]
if elem["capture_switch"] is None:
return
selem = self.selems[elem["index"]]
snd_mixer_selem_get_capture_switch(selem, <snd_mixer_selem_channel_id_t>0, &value)
return bool(value)
def set_capture_switch(self, elem, value):
cdef snd_mixer_elem_t * selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
elem = self._elements[elem]
if elem["capture_switch"] is None:
return
selem = self.selems[elem["index"]]
value = int(bool(value))
snd_mixer_selem_set_capture_switch_all(selem, value)
def __del__(self):
#never called
snd_mixer_close(self.handle)

502
alsa.pyx.old Normal file
View file

@ -0,0 +1,502 @@
# do some opaque struct typedefs to make const typedefs possible
cdef extern from "alsa/asoundlib.h":
ctypedef struct snd_mixer_t
ctypedef struct snd_mixer_class_t
ctypedef struct snd_pcm_t
ctypedef struct snd_mixer_elem_t
ctypedef struct snd_mixer_selem_id_t
# define const ptr types as cython doesnt know const
cdef extern from *:
ctypedef char* const_char_ptr "const char*"
ctypedef snd_mixer_selem_id_t* const_snd_mixer_selem_id_t_ptr "const snd_mixer_selem_id_t *"
ctypedef snd_mixer_elem_t* const_snd_mixer_elem_t_ptr "const snd_mixer_elem_t *"
ctypedef snd_mixer_t* const_snd_mixer_t_ptr "const snd_mixer_t *"
cdef extern from "stdlib.h":
ctypedef unsigned long size_t
void *calloc(size_t count, size_t size)
void *malloc(size_t size)
void free(void *ptr)
void *realloc(void *ptr, size_t size)
cdef extern from "alloca.h":
void *alloca(size_t size)
cdef extern from "string.h":
void *memset (void *s, int c, size_t n)
cdef extern from "sys/poll.h":
struct pollfd:
int fd
short int events
cdef extern from "alsa/asoundlib.h":
ctypedef enum snd_mixer_selem_regopt_abstract:
pass
ctypedef enum snd_mixer_elem_type_t:
pass
ctypedef enum snd_mixer_selem_channel_id_t:
pass
struct snd_mixer_selem_regopt:
pass
ctypedef int (*snd_mixer_compare_t)(const_snd_mixer_elem_t_ptr e1, const_snd_mixer_elem_t_ptr e2)
ctypedef int (*snd_mixer_callback_t)(snd_mixer_t *ctl, unsigned int mask, snd_mixer_elem_t *elem)
ctypedef int (*snd_mixer_elem_callback_t)(snd_mixer_elem_t *elem, unsigned int mask)
int snd_mixer_open(snd_mixer_t **mixer, int mode)
int snd_mixer_close(snd_mixer_t *mixer)
snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer)
snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer)
int snd_mixer_handle_events(snd_mixer_t *mixer)
int snd_mixer_attach(snd_mixer_t *mixer, const_char_ptr name)
int snd_mixer_detach(snd_mixer_t *mixer, const_char_ptr name)
int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer)
int snd_mixer_poll_descriptors(snd_mixer_t *mixer, pollfd *pfds, unsigned int space)
int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, pollfd *pfds, unsigned int nfds, unsigned short *revents)
int snd_mixer_load(snd_mixer_t *mixer)
void snd_mixer_free(snd_mixer_t *mixer)
int snd_mixer_wait(snd_mixer_t *mixer, int timeout)
int snd_mixer_set_compare(snd_mixer_t *mixer, snd_mixer_compare_t msort)
void snd_mixer_set_callback(snd_mixer_t *obj, snd_mixer_callback_t val)
void * snd_mixer_get_callback_private(const_snd_mixer_t_ptr obj)
void snd_mixer_set_callback_private(snd_mixer_t *obj, void * val)
unsigned int snd_mixer_get_count(const_snd_mixer_t_ptr obj)
int snd_mixer_class_unregister(snd_mixer_class_t *clss)
snd_mixer_elem_t *snd_mixer_elem_next(snd_mixer_elem_t *elem)
snd_mixer_elem_t *snd_mixer_elem_prev(snd_mixer_elem_t *elem)
void snd_mixer_elem_set_callback(snd_mixer_elem_t *obj, snd_mixer_elem_callback_t val)
void * snd_mixer_elem_get_callback_private(const_snd_mixer_elem_t_ptr obj)
void snd_mixer_elem_set_callback_private(snd_mixer_elem_t *obj, void * val)
snd_mixer_elem_type_t snd_mixer_elem_get_type(const_snd_mixer_elem_t_ptr obj)
int snd_mixer_selem_register(snd_mixer_t *mixer, snd_mixer_selem_regopt *options, snd_mixer_class_t **classp)
void snd_mixer_selem_get_id(snd_mixer_elem_t *element, snd_mixer_selem_id_t *id)
const_char_ptr snd_mixer_selem_get_name(snd_mixer_elem_t *elem)
unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem)
snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer, const_snd_mixer_selem_id_t_ptr id)
int snd_mixer_selem_is_active(snd_mixer_elem_t *elem)
int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel)
int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel)
int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_common_volume(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_volume_joined(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_common_switch(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem)
int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem)
int snd_mixer_selem_ask_playback_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue)
int snd_mixer_selem_ask_capture_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue)
int snd_mixer_selem_ask_playback_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value)
int snd_mixer_selem_ask_capture_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value)
int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
int snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
int snd_mixer_selem_get_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value)
int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value)
int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value)
int snd_mixer_selem_set_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir)
int snd_mixer_selem_set_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir)
int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value)
int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value)
int snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *elem, long value, int dir)
int snd_mixer_selem_set_capture_dB_all(snd_mixer_elem_t *elem, long value, int dir)
int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value)
int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value)
int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value)
int snd_mixer_selem_get_playback_volume_range(snd_mixer_elem_t *elem, long *min, long *max)
int snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem, long *min, long *max)
int snd_mixer_selem_set_playback_volume_range(snd_mixer_elem_t *elem, long min, long max)
int snd_mixer_selem_get_capture_volume_range(snd_mixer_elem_t *elem, long *min, long *max)
int snd_mixer_selem_get_capture_dB_range(snd_mixer_elem_t *elem, long *min, long *max)
int snd_mixer_selem_set_capture_volume_range(snd_mixer_elem_t *elem, long min, long max)
int snd_mixer_selem_is_enumerated(snd_mixer_elem_t *elem)
int snd_mixer_selem_is_enum_playback(snd_mixer_elem_t *elem)
int snd_mixer_selem_is_enum_capture(snd_mixer_elem_t *elem)
int snd_mixer_selem_get_enum_items(snd_mixer_elem_t *elem)
int snd_mixer_selem_get_enum_item_name(snd_mixer_elem_t *elem, unsigned int idx, size_t maxlen, char *str)
int snd_mixer_selem_get_enum_item(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int *idxp)
int snd_mixer_selem_set_enum_item(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int idx)
size_t snd_mixer_selem_id_sizeof()
int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr)
void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj)
void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const_snd_mixer_selem_id_t_ptr src)
const_char_ptr snd_mixer_selem_id_get_name(const_snd_mixer_selem_id_t_ptr obj)
unsigned int snd_mixer_selem_id_get_index(const_snd_mixer_selem_id_t_ptr obj)
void snd_mixer_selem_id_set_name(snd_mixer_selem_id_t *obj, const_char_ptr val)
void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val)
cdef int get_handle(snd_mixer_t **handle):
cdef int err
err = snd_mixer_open(handle, 0)
if err < 0: return err
err = snd_mixer_attach(handle[0], "hw:0")
if err < 0: return err
err = snd_mixer_selem_register(handle[0], NULL, NULL)
if err < 0: return err
err = snd_mixer_load(handle[0])
if err < 0: return err
return 0
cdef struct selem:
snd_mixer_elem_t *elem
selem *next
SANE_CONTROL_COUNT = 16 # assuming a sane value of 16 controls
cdef class Mixer:
cdef snd_mixer_t *handle
cdef snd_mixer_elem_t **selems
_elements = dict()
def __init__(self):
cdef int selem_count = 0, selems_size = SANE_CONTROL_COUNT
cdef snd_mixer_elem_t *temp_elem
cdef snd_mixer_elem_t **temp_elems
get_handle(&self.handle)
temp_elem = snd_mixer_first_elem(self.handle)
if not temp_elem:
return
selem_count = 1
self.selems = <snd_mixer_elem_t **>malloc(selems_size*sizeof(snd_mixer_elem_t *))
self.selems[0] = temp_elem
while True:
temp_elem = snd_mixer_elem_next(temp_elem)
if not temp_elem:
break
selem_count += 1
if selem_count > selems_size:
# running out of space - realloc double the size
selems_size *= 2
temp_elems = <snd_mixer_elem_t **>realloc(self.selems, selems_size*sizeof(snd_mixer_elem_t *))
if not temp_elems:
raise MemoryError
return
self.selems = temp_elems
self.selems[selem_count-1] = temp_elem
self._elements[snd_mixer_selem_get_name(self.selems[i])] = {
"index": selem_count-1,
"enumeration": None,
"playback_volume": None,
"playback_switch": None,
"capture_volume": None,
"capture_switch": None
}
# shrink allocated memory to exact needed size
self.selems = <snd_mixer_elem_t **>realloc(self.selems, selem_count*sizeof(snd_mixer_elem_t *))
def get_enum_items(self, elem):
cdef snd_mixer_elem_t *selem
if elem not in self._elements:
raise KeyError("not a valid control", elem)
elem = self._elements[elem]
if not elem["is_enumerated"]:
return None
index = elem["index"]
selem = self.selems[index]
def get_enum_item(self):
pass
def set_enum_item(self):
pass
def get_playback_volume(self):
pass
def set_playback_volume(self):
pass
def get_capture_volume(self):
pass
def set_capture_volume(self):
pass
def get_playback_switch(self):
pass
def set_playback_switch(self):
pass
def get_capture_switeh(self):
pass
def set_capture_switch(self):
pass
def __del__(self):
print "Destructor"
snd_mixer_close(self.handle)
m = Mixer()
print m.get_enum_items("IEC958 Playback Source")
def list_elems3():
cdef snd_mixer_t *handle
cdef snd_mixer_elem_t *elem
cdef snd_mixer_selem_id_t *sid
cdef long pmin, pmax, cmin, cmax, lvalue
cdef int enum_items_count, ivalue
cdef char name[32]
cdef unsigned int idx
sid = <snd_mixer_selem_id_t *>alloca(snd_mixer_selem_id_sizeof())
memset(sid, 0, snd_mixer_selem_id_sizeof())
get_handle(&handle)
elem = snd_mixer_first_elem(handle)
print "\tpvol\tcvol\tpsw\tcsw\tenum"
while elem:
print snd_mixer_selem_get_name(elem),
print "\t",
if snd_mixer_selem_has_playback_volume(elem):
snd_mixer_selem_get_playback_volume(elem, <snd_mixer_selem_channel_id_t>0, &lvalue)
print "%d\t"%lvalue,
else:
print "\t",
if snd_mixer_selem_has_playback_switch(elem):
snd_mixer_selem_get_playback_switch(elem, <snd_mixer_selem_channel_id_t>0, &ivalue)
print "%d\t"%ivalue,
else:
print "\t",
if snd_mixer_selem_has_capture_volume(elem):
snd_mixer_selem_get_capture_volume(elem, <snd_mixer_selem_channel_id_t>0, &lvalue)
print "%d\t"%lvalue,
else:
print "\t",
if snd_mixer_selem_has_capture_switch(elem):
snd_mixer_selem_get_capture_switch(elem, <snd_mixer_selem_channel_id_t>0, &ivalue)
print "%d\t"%ivalue,
else:
print "\t",
if snd_mixer_selem_is_enumerated(elem):
snd_mixer_selem_get_enum_item(elem, <snd_mixer_selem_channel_id_t>0, &idx)
print "%d\t"%idx,
else:
print "\t",
print
elem = snd_mixer_elem_next(elem)
snd_mixer_close(handle)
def list_elems2():
cdef snd_mixer_t *handle
cdef snd_mixer_elem_t *elem
cdef snd_mixer_selem_id_t *sid
cdef long pmin, pmax, cmin, cmax
cdef int enum_items_count
cdef char name[32]
sid = <snd_mixer_selem_id_t *>alloca(snd_mixer_selem_id_sizeof())
memset(sid, 0, snd_mixer_selem_id_sizeof())
get_handle(&handle)
elem = snd_mixer_first_elem(handle)
print "\tpvol\tcvol\tpsw\tcsw\tenum"
while elem:
print snd_mixer_selem_get_name(elem),
print "\t",
if snd_mixer_selem_has_playback_volume(elem):
snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax)
print "%d-%d\t"%(pmin, pmax),
else:
print "\t",
if snd_mixer_selem_has_playback_switch(elem):
print "yes\t",
else:
print "\t",
if snd_mixer_selem_has_capture_volume(elem):
snd_mixer_selem_get_capture_volume_range(elem, &cmin, &cmax)
print "%d-%d\t"%(cmin, cmax),
else:
print "\t",
if snd_mixer_selem_has_capture_switch(elem):
print "yes\t",
else:
print "\t",
if snd_mixer_selem_is_enumerated(elem):
enum_items_count = snd_mixer_selem_get_enum_items(elem)
for i from 0 <= i < enum_items_count:
snd_mixer_selem_get_enum_item_name(elem, i, sizeof(name)-1, name)
print "%s,"%name,
else:
print "\t",
print
elem = snd_mixer_elem_next(elem)
snd_mixer_close(handle)
def list_elems():
cdef long pmin, pmax, cmin, cmax, ival
cdef int enum_items_count, value
cdef unsigned int idx
cdef char name[32]
cdef snd_mixer_t *handle
get_handle(&handle)
# poll fd
count = snd_mixer_poll_descriptors_count(handle)
print "poll count:", count
cdef pollfd* fds = <pollfd*>calloc(count, sizeof(pollfd))
snd_mixer_poll_descriptors(handle, fds, count)
cdef pollfd fd
for i in xrange(count):
fd = fds[i]
print "poll fd: ", fd.fd
print "poll events: ", fd.events
cdef snd_mixer_elem_t *elem
cdef snd_mixer_selem_id_t *sid = <snd_mixer_selem_id_t *>alloca(snd_mixer_selem_id_sizeof())
memset(sid, 0, snd_mixer_selem_id_sizeof())
elem = snd_mixer_first_elem(handle)
while elem:
print
snd_mixer_selem_get_id(elem, sid)
print "name:", snd_mixer_selem_id_get_name(sid)
print "index:", snd_mixer_selem_id_get_index(sid)
playback_volume_or_switch = False
capture_volume_or_switch = False
if snd_mixer_selem_has_common_volume(elem):
print "Common Volume"
if snd_mixer_selem_has_playback_volume(elem):
playback_volume_or_switch = True
print "Playback Volume"
if snd_mixer_selem_has_playback_volume_joined(elem):
print "Playback Volume Joined"
if snd_mixer_selem_has_capture_volume(elem):
capture_volume_or_switch = True
print "Capture Volume"
if snd_mixer_selem_has_capture_volume_joined(elem):
print "Capture Volume Joined"
if snd_mixer_selem_has_common_switch(elem):
print "Common Switch"
if snd_mixer_selem_has_playback_switch(elem):
playback_volume_or_switch = True
print "Playback Switch"
if snd_mixer_selem_has_playback_switch_joined(elem):
print "Playback Switch Joined"
if snd_mixer_selem_has_capture_switch(elem):
capture_volume_or_switch = True
print "Capture Switch"
if snd_mixer_selem_has_capture_switch_joined(elem):
print "Capture Switch Joined"
if snd_mixer_selem_has_capture_switch_exclusive(elem):
print "Capture Switch Exclusive"
playback_channel_count = 0
if playback_volume_or_switch:
if snd_mixer_selem_is_playback_mono(elem):
snd_mixer_selem_get_playback_volume(elem, <snd_mixer_selem_channel_id_t>0, &ival)
print "Playback Volume Channel Mono:", ival
snd_mixer_selem_get_playback_switch(elem, <snd_mixer_selem_channel_id_t>0, &value)
print "Playback Switch Mono:", value
playback_channel_count = 1
else:
for i in xrange(32):
if snd_mixer_selem_has_playback_channel(elem, i):
snd_mixer_selem_get_playback_volume(elem, i, &ival)
print "Playback Volume Channel %d:"%i, ival
snd_mixer_selem_get_playback_switch(elem, i, &value)
print "Playback Switch Channel %d:"%i, value
playback_channel_count += 1
else:
break
print "Playback Channel Count:", playback_channel_count
capture_channel_count = 0
if capture_volume_or_switch:
if snd_mixer_selem_is_capture_mono(elem):
snd_mixer_selem_get_capture_volume(elem, <snd_mixer_selem_channel_id_t>0, &ival)
print "Capture Volume Channel Mono:", ival
snd_mixer_selem_get_capture_switch(elem, <snd_mixer_selem_channel_id_t>0, &value)
print "Capture Switch Mono:", value
capture_channel_count = 1
else:
for i in xrange(32):
if snd_mixer_selem_has_capture_channel(elem, i):
snd_mixer_selem_get_capture_volume(elem, i, &ival)
print "Capture Volume Channel %d:"%i, ival
snd_mixer_selem_get_capture_switch(elem, i, &value)
print "Capture Switch Channel %d:"%i, value
capture_channel_count += 1
else:
break
print "Capture Channel Count:", capture_channel_count
snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax)
snd_mixer_selem_get_capture_volume_range(elem, &cmin, &cmax)
print "Playback Volume Range:", pmin, pmax
print "Capture Volume Range:", cmin, cmax
if snd_mixer_selem_is_enumerated(elem):
snd_mixer_selem_get_enum_item(elem, <snd_mixer_selem_channel_id_t>0, &idx)
print "Selected enum item:", idx
enum_items_count = snd_mixer_selem_get_enum_items(elem)
print "Enumerates over %d Items: "%enum_items_count,
for i from 0 <= i < enum_items_count:
snd_mixer_selem_get_enum_item_name(elem, i, sizeof(name)-1, name)
print "%s,"%name,
print
elem = snd_mixer_elem_next(elem)
snd_mixer_close(handle)
#list_elems3()
#cdef snd_mixer_t *handle
#
#get_handle(&handle)
#
#cdef snd_mixer_elem_t *elem
#cdef snd_mixer_selem_id_t *sid = <snd_mixer_selem_id_t *>alloca(snd_mixer_selem_id_sizeof())
#memset(sid, 0, snd_mixer_selem_id_sizeof())
#
#snd_mixer_selem_id_set_index(sid, 0)
#snd_mixer_selem_id_set_name(sid, "Master")
#elem = snd_mixer_find_selem(handle, sid)
#
#snd_mixer_selem_set_playback_volume(elem, <snd_mixer_selem_channel_id_t>0, 32)
#
#snd_mixer_selem_id_set_index(sid, 0)
#snd_mixer_selem_id_set_name(sid, "IEC958 Playback Source")
#elem = snd_mixer_find_selem(handle, sid)
#
#print snd_mixer_selem_set_enum_item(elem, <snd_mixer_selem_channel_id_t>0, 0)
#snd_mixer_selem_id_set_index(sid, 0)
#snd_mixer_selem_id_set_name(sid, "Mono Mixer Bypass Playback Swit")
#elem = snd_mixer_find_selem(handle, sid)
#snd_mixer_selem_set_playback_switch(elem, <snd_mixer_selem_channel_id_t>0, 1)

123
mixer.py Normal file
View file

@ -0,0 +1,123 @@
from alsa import Mixer
m = Mixer()
PVOL, PSW, CVOL, CSW, ENUM = m.set_playback_volume, m.set_playback_switch, m.set_capture_volume, m.set_capture_switch, m.set_enum_item
controls = [
(PVOL, "Headphone"),
(PSW, "Headphone Playback ZC"),
(PVOL, "Speaker"),
(PSW, "Speaker Playback ZC"),
(PVOL, "Bass"), (CVOL, "Bass"),
(ENUM, "Bass Boost"),
(ENUM, "Bass Filter"),
(PVOL, "Treble"), (CVOL, "Treble"),
(ENUM, "Treble Cut-off"),
(PVOL, "PCM"), (CVOL, "PCM"),
(PVOL, "Sidetone"), (CVOL, "Sidetone"),
(ENUM, "Line Left Mux"),
(ENUM, "Line Mixer"),
(ENUM, "Line Mono Mux"),
(ENUM, "Line Right Mux"),
(ENUM, "Mic Selection Mux"),
(ENUM, "Mic Sidetone Mux"),
(CVOL, "Mic1"),
(CVOL, "Mic2"),
(PVOL, "Mono"),
(ENUM, "Mono 2 Mux"),
(PVOL, "Mono Bypass"),
(PSW, "Mono Mixer Bypass"),
(PSW, "Mono Mixer Left"),
(PSW, "Mono Mixer Right"),
(PSW, "Mono Mixer Sidetone"),
(PSW, "Mono Mixer Voice"),
(PSW, "Mono Playback ZC"),
(PVOL, "Mono Sidetone"),
(PVOL, "Mono Voice"),
(PSW, "Playback 6dB Attenuate"),
(CSW, "Playback Mixer Left"),
(PSW, "Playback Mixer Right"),
(PSW, "Playback Mixer Voice"),
(ENUM, "Playback Mono Mix"),
(ENUM, "Playback Phase"),
(CVOL, "Capture"), (CSW, "Capture"),
(PSW, "Capture 6dB Attenuate"),
(PSW, "Capture Filter"),
(ENUM, "Capture Filter Cut-off"),
(ENUM, "Capture Filter Select"),
(ENUM, "Capture Left Mixer"),
(ENUM, "Capture Left Mux"),
(ENUM, "Capture Right Mixer"),
(ENUM, "Capture Right Mux"),
(PSW, "Capture ZC"),
(PVOL, "3D"), (PSW, "3D"), (CVOL, "3D"),
(ENUM, "3D Function"),
(ENUM, "3D Lower Cut-off"),
(ENUM, "3D Upper Cut-off"),
(CVOL, "ADC"),
(ENUM, "ADC Data Select"),
(PVOL, "ALC Capture Attack Time"), (CVOL, "ALC Capture Attack Time"),
(PVOL, "ALC Capture Decay Time"), (CVOL, "ALC Capture Decay Time"),
(ENUM, "ALC Capture Function"),
(PVOL, "ALC Capture Hold Time"), (CVOL, "ALC Capture Hold Time"),
(PVOL, "ALC Capture Max"), (CVOL, "ALC Capture Max"),
(PSW, "ALC Capture NG"),
(PVOL, "ALC Capture NG Threshold"), (CVOL, "ALC Capture NG Threshold"),
(ENUM, "ALC Capture NG Type"),
(PVOL, "ALC Capture Target"), (CVOL, "ALC Capture Target"),
(PSW, "ALC Capture ZC"),
(CSW, "ALC Mixer Line"),
(CSW, "ALC Mixer Mic1"),
(CSW, "ALC Mixer Mic2"),
(CSW, "ALC Mixer Rx"),
(PSW, "Amp Spk"),
(PVOL, "Bypass"),
(ENUM, "DAI Mode"),
(ENUM, "De-emphasis"),
(PSW, "GSM Line In"),
(PSW, "GSM Line Out"),
(PSW, "Handset Mic"),
(PSW, "Handset Spk"),
(PSW, "Headset Mic"),
(PSW, "Left Mixer Bypass"),
(PSW, "Left Mixer Left"),
(PSW, "Left Mixer Sidetone"),
(PSW, "Left Mixer Voice"),
(ENUM, "Out3 Mux"),
(ENUM, "Out4 Mux"),
(ENUM, "ROUT2 Phase"),
(PSW, "Right Mixer Bypass"),
(PSW, "Right Mixer Right"),
(PSW, "Right Mixer Sidetone"),
(PSW, "Right Mixer Voice"),
(PVOL, "Voice"),
(CVOL, "Voice Sidetone")
]
def restore_defaults():
for control in controls:
func, elem = control
func(elem, 0)
restore_defaults()
def load_stereoout():
PVOL("Headphone", 0.9)
PVOL("PCM", 1.0)
PSW("Amp Spk", True)
PSW("Left Mixer Left", True)
PSW("Right Mixer Right", True)
PSW("Stereo Out", True)
#load_stereoout()
def load_handsetout():
PVOL("Headphone", 0.9)
PVOL("PCM", 1.0)
PSW("Left Mixer Left", True)
PSW("Right Mixer Right", True)
PSW("Stereo Out", True)
load_stereoout()

22
setup.py Normal file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension('alsa', ['alsa.pyx'],
libraries=['asound'],
# include_dirs=['/usr/include/alsa/'],
# extra_compile_args=["-Wno-cast-qual", "-Wno-strict-prototypes"],
)]
setup(
name = 'alsa',
# version='1.12',
# description='pyneod daemon suite',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
author='Johannes Schauer',
author_email='josch@pyneo.org',
)
# vim:tw=0:nowrap