diff options
author | Jaroslav Kysela <perex@perex.cz> | 2008-04-21 11:44:20 +0200 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-04-21 11:44:20 +0200 |
commit | 058dde8b7da6f7b725e4ef8b9b237f2a5c6ff01e (patch) | |
tree | d448c9cd2544c67cce3bafe99ad92469ca1dae09 | |
parent | 82af1df465181da783d85256afdda26942eaecbf (diff) | |
download | alsa-lib-058dde8b7da6f7b725e4ef8b9b237f2a5c6ff01e.tar.gz |
implemented integer volume <-> dB volume conversion functions for simple mixer
-rw-r--r-- | include/mixer.h | 4 | ||||
-rw-r--r-- | include/mixer_abst.h | 2 | ||||
-rw-r--r-- | modules/mixer/simple/python.c | 48 | ||||
-rw-r--r-- | src/mixer/simple.c | 58 | ||||
-rw-r--r-- | src/mixer/simple_none.c | 29 |
5 files changed, 139 insertions, 2 deletions
diff --git a/include/mixer.h b/include/mixer.h index ac46b121..59deb9f2 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -250,6 +250,10 @@ 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); diff --git a/include/mixer_abst.h b/include/mixer_abst.h index d39d8358..7844b191 100644 --- a/include/mixer_abst.h +++ b/include/mixer_abst.h @@ -82,6 +82,8 @@ struct sm_elem_ops { int (*get_range)(snd_mixer_elem_t *elem, int dir, long *min, long *max); int (*set_range)(snd_mixer_elem_t *elem, int dir, long min, long max); int (*get_dB_range)(snd_mixer_elem_t *elem, int dir, long *min, long *max); + int (*ask_vol_dB)(snd_mixer_elem_t *elem, int dir, long value, long *dbValue); + int (*ask_dB_vol)(snd_mixer_elem_t *elem, int dir, long dbValue, long *value, int xdir); int (*get_volume)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long *value); int (*get_dB)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long *value); int (*set_volume)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value); diff --git a/modules/mixer/simple/python.c b/modules/mixer/simple/python.c index 6d9b9fd2..c822c52a 100644 --- a/modules/mixer/simple/python.c +++ b/modules/mixer/simple/python.c @@ -204,7 +204,7 @@ static int set_range_ops(snd_mixer_elem_t *elem, int dir, } static int get_x_ops(snd_mixer_elem_t *elem, int dir, - snd_mixer_selem_channel_id_t channel, long *value, + long channel, long *value, const char *attr) { PyObject *obj1, *res; @@ -251,6 +251,49 @@ static int get_switch_ops(snd_mixer_elem_t *elem, int dir, return res; } +static int ask_vol_dB_ops(snd_mixer_elem_t *elem, + int dir, + long value, + long *dbValue) +{ + return get_x_ops(elem, dir, value, dbValue, "opsGetVolDB"); +} + +static int ask_dB_vol_ops(snd_mixer_elem_t *elem, + int dir, + long value, + long *dbValue, + int xdir) +{ + PyObject *obj1, *res; + struct pymelem *pymelem = melem_to_pymelem(elem); + int err; + + obj1 = PyTuple_New(3); + PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(dir)); + PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong(value)); + PyTuple_SET_ITEM(obj1, 2, PyInt_FromLong(xdir)); + err = pcall(pymelem, "opsGetDBVol", obj1, &res); + if (err >= 0) { + err = !PyInt_Check(PyTuple_GetItem(res, 1)); + if (err) { + err = !PyLong_Check(PyTuple_GetItem(res, 1)); + if (err) { + PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); + PyErr_Print(); + PyErr_Clear(); + err = -EIO; + } else { + *dbValue = PyLong_AsLong(PyTuple_GetItem(res, 1)); + } + } else { + *dbValue = PyInt_AsLong(PyTuple_GetItem(res, 1)); + } + } + Py_XDECREF(res); + return err; +} + static int get_dB_ops(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, @@ -278,7 +321,6 @@ static int set_volume_ops(snd_mixer_elem_t *elem, int dir, return pcall(pymelem, "opsSetVolume", obj1, NULL); } - static int set_switch_ops(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int value) { @@ -384,6 +426,8 @@ static struct sm_elem_ops simple_python_ops = { .get_range = get_range_ops, .get_dB_range = get_dB_range_ops, .set_range = set_range_ops, + .ask_vol_dB = ask_vol_dB_ops, + .ask_dB_vol = ask_dB_vol_ops, .get_volume = get_volume_ops, .get_dB = get_dB_ops, .set_volume = set_volume_ops, diff --git a/src/mixer/simple.c b/src/mixer/simple.c index ae948ace..c44f8b42 100644 --- a/src/mixer/simple.c +++ b/src/mixer/simple.c @@ -358,6 +358,35 @@ int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem) } /** + * \brief Return corresponding dB value to an integer playback volume for a mixer simple element + * \param elem Mixer simple element handle + * \param value value to be converted to dB range + * \param dBvalue pointer to returned dB value + * \return 0 on success otherwise a negative error code + */ +int snd_mixer_selem_ask_playback_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue) +{ + CHECK_BASIC(elem); + CHECK_DIR(elem, SM_CAP_PVOLUME); + return sm_selem_ops(elem)->ask_vol_dB(elem, SM_PLAY, value, dBvalue); +} + +/** + * \brief Return corresponding integer playback volume for given dB value for a mixer simple element + * \param elem Mixer simple element handle + * \param value value to be converted to dB range + * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above) + * \param dBvalue pointer to returned dB value + * \return 0 on success otherwise a negative error code + */ +int snd_mixer_selem_ask_playback_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value) +{ + CHECK_BASIC(elem); + CHECK_DIR(elem, SM_CAP_PVOLUME); + return sm_selem_ops(elem)->ask_dB_vol(elem, SM_PLAY, dBvalue, value, dir); +} + +/** * \brief Return value of playback volume control of a mixer simple element * \param elem Mixer simple element handle * \param channel mixer simple element channel identifier @@ -658,6 +687,35 @@ int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem) } /** + * \brief Return corresponding dB value to an integer capture volume for a mixer simple element + * \param elem Mixer simple element handle + * \param value value to be converted to dB range + * \param dBvalue pointer to returned dB value + * \return 0 on success otherwise a negative error code + */ +int snd_mixer_selem_ask_capture_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue) +{ + CHECK_BASIC(elem); + CHECK_DIR(elem, SM_CAP_CVOLUME); + return sm_selem_ops(elem)->ask_vol_dB(elem, SM_CAPT, value, dBvalue); +} + +/** + * \brief Return corresponding integer capture volume for given dB value for a mixer simple element + * \param elem Mixer simple element handle + * \param dBvalue dB value to be converted to integer range + * \param value pointer to returned integer value + * \param dir select direction (-1 = accurate or first bellow, 0 = accurate, 1 = accurate or first above) + * \return 0 on success otherwise a negative error code + */ +int snd_mixer_selem_ask_capture_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value) +{ + CHECK_BASIC(elem); + CHECK_DIR(elem, SM_CAP_CVOLUME); + return sm_selem_ops(elem)->ask_dB_vol(elem, SM_CAPT, dBvalue, value, dir); +} + +/** * \brief Return value of capture volume control of a mixer simple element * \param elem Mixer simple element handle * \param channel mixer simple element channel identifier diff --git a/src/mixer/simple_none.c b/src/mixer/simple_none.c index b490e1c1..ef277de2 100644 --- a/src/mixer/simple_none.c +++ b/src/mixer/simple_none.c @@ -1174,6 +1174,21 @@ static int convert_from_dB(snd_hctl_elem_t *ctl, struct selem_str *rec, db_gain, value, xdir); } +static int ask_vol_dB_ops(snd_mixer_elem_t *elem, + int dir, + long value, + long *dBvalue) +{ + selem_none_t *s = snd_mixer_elem_get_private(elem); + selem_ctl_t *c; + + c = get_selem_ctl(s, dir); + if (! c) + return -EINVAL; + int res = convert_to_dB(c->elem, &s->str[dir], value, dBvalue); + return res; +} + static int get_dB_ops(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, @@ -1219,6 +1234,18 @@ static int set_volume_ops(snd_mixer_elem_t *elem, int dir, return 0; } +static int ask_dB_vol_ops(snd_mixer_elem_t *elem, int dir, + long dbValue, long *value, int xdir) +{ + selem_none_t *s = snd_mixer_elem_get_private(elem); + selem_ctl_t *c; + + c = get_selem_ctl(s, dir); + if (! c) + return -EINVAL; + return convert_from_dB(c->elem, &s->str[dir], dbValue, value, xdir); +} + static int set_dB_ops(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long db_gain, int xdir) @@ -1350,6 +1377,8 @@ static struct sm_elem_ops simple_none_ops = { .get_range = get_range_ops, .get_dB_range = get_dB_range_ops, .set_range = set_range_ops, + .ask_vol_dB = ask_vol_dB_ops, + .ask_dB_vol = ask_dB_vol_ops, .get_volume = get_volume_ops, .get_dB = get_dB_ops, .set_volume = set_volume_ops, |