modem.conf Off-hook improve behavior

Only restore the old value if it differs from the requested
value, because if it has changed restoring the old value
overrides the change.  Take for example, a voice modem with
a .conf that sets preserve off-hook.  Start playback (on-hook
to off-hook), start record (off-hook to off-hook), stop
playback (off-hook to restore on-hook), stop record (on-hook
to restore off-hook), Clearly you don't want to leave the
modem "on the phone" now that there isn't any playback or
recording active.

Signed-off-by: David Fries <david@fries.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
David Fries 2009-12-25 14:22:38 -06:00 committed by Takashi Iwai
parent d3c6e2b097
commit 63acb87329
3 changed files with 24 additions and 1 deletions

View file

@ -423,6 +423,7 @@ int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr);
void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj);
void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj);
void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst, const snd_ctl_elem_value_t *src);
int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left, const snd_ctl_elem_value_t *right);
void snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t *obj, snd_ctl_elem_id_t *ptr);
unsigned int snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t *obj);
snd_ctl_elem_iface_t snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t *obj);

View file

@ -2248,6 +2248,18 @@ void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst, const snd_ctl_elem_value
*dst = *src;
}
/**
* \brief compare one #snd_ctl_elem_value_t to another
* \param dst pointer to destination
* \param src pointer to source
* \return 0 on match, less than or greater than otherwise, see memcmp
*/
int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left, const snd_ctl_elem_value_t *right)
{
assert(left && right);
return memcmp(left, right, sizeof(*left));
}
/**
* \brief Get CTL element identifier of a CTL element id/value
* \param obj CTL element id/value

View file

@ -192,7 +192,17 @@ int snd_sctl_remove(snd_sctl_t *h)
return err;
}
}
if (elem->preserve) {
/* Only restore the old value if it differs from the requested
* value, because if it has changed restoring the old value
* overrides the change. Take for example, a voice modem with
* a .conf that sets preserve off-hook. Start playback (on-hook
* to off-hook), start record (off-hook to off-hook), stop
* playback (off-hook to restore on-hook), stop record (on-hook
* to restore off-hook), Clearly you don't want to leave the
* modem "on the phone" now that there isn't any playback or
* recording active.
*/
if (elem->preserve && snd_ctl_elem_value_compare(elem->val, elem->old)) {
err = snd_ctl_elem_write(h->ctl, elem->old);
if (err < 0) {
SNDERR("Cannot restore ctl elem");