// ----------------------------------------------------------------------------
+ALSAControl::ALSAControl(const char *device)
+{
+ snd_ctl_open(&mHandle, device, 0);
+}
+
+ALSAControl::~ALSAControl()
+{
+ if (mHandle) snd_ctl_close(mHandle);
+}
+
+status_t ALSAControl::get(const char *name, unsigned int &value, int index)
+{
+ if (!mHandle) return NO_INIT;
+
+ snd_ctl_elem_id_t *id;
+ snd_ctl_elem_info_t *info;
+ snd_ctl_elem_value_t *control;
+
+ snd_ctl_elem_id_alloca(&id);
+ snd_ctl_elem_info_alloca(&info);
+ snd_ctl_elem_value_alloca(&control);
+
+ snd_ctl_elem_id_set_name(id, name);
+ snd_ctl_elem_info_set_id(info, id);
+
+ int ret = snd_ctl_elem_info(mHandle, info);
+ if (ret < 0) return BAD_VALUE;
+
+ snd_ctl_elem_info_get_id(info, id);
+ snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(info);
+ unsigned int count = snd_ctl_elem_info_get_count(info);
+ if ((unsigned int)index >= count) return BAD_VALUE;
+
+ snd_ctl_elem_value_set_id(control, id);
+
+ ret = snd_ctl_elem_read(mHandle, control);
+ if (ret < 0) return BAD_VALUE;
+
+ switch (type) {
+ case SND_CTL_ELEM_TYPE_BOOLEAN:
+ value = snd_ctl_elem_value_get_boolean(control, index);
+ break;
+ case SND_CTL_ELEM_TYPE_INTEGER:
+ value = snd_ctl_elem_value_get_integer(control, index);
+ break;
+ case SND_CTL_ELEM_TYPE_INTEGER64:
+ value = snd_ctl_elem_value_get_integer64(control, index);
+ break;
+ case SND_CTL_ELEM_TYPE_ENUMERATED:
+ value = snd_ctl_elem_value_get_enumerated(control, index);
+ break;
+ case SND_CTL_ELEM_TYPE_BYTES:
+ value = snd_ctl_elem_value_get_byte(control, index);
+ break;
+ default:
+ return BAD_VALUE;
+ }
+
+ return NO_ERROR;
+}
+
+status_t ALSAControl::set(const char *name, unsigned int value, int index)
+{
+ if (!mHandle) return NO_INIT;
+
+ snd_ctl_elem_id_t *id;
+ snd_ctl_elem_info_t *info;
+ snd_ctl_elem_value_t *control;
+
+ snd_ctl_elem_id_alloca(&id);
+ snd_ctl_elem_info_alloca(&info);
+ snd_ctl_elem_value_alloca(&control);
+
+ snd_ctl_elem_id_set_name(id, name);
+ snd_ctl_elem_info_set_id(info, id);
+
+ int ret = snd_ctl_elem_info(mHandle, info);
+ if (ret < 0) return BAD_VALUE;
+
+ snd_ctl_elem_info_get_id(info, id);
+ snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(info);
+ unsigned int count = snd_ctl_elem_info_get_count(info);
+ if ((unsigned int)index >= count) return BAD_VALUE;
+
+ if (index == -1)
+ index = 0; // Range over all of them
+ else
+ count = index + 1; // Just do the one specified
+
+ snd_ctl_elem_value_set_id(control, id);
+
+ for (unsigned int i = index; i < count; i++)
+ switch (type) {
+ case SND_CTL_ELEM_TYPE_BOOLEAN:
+ snd_ctl_elem_value_set_boolean(control, i, value);
+ break;
+ case SND_CTL_ELEM_TYPE_INTEGER:
+ snd_ctl_elem_value_set_integer(control, i, value);
+ break;
+ case SND_CTL_ELEM_TYPE_INTEGER64:
+ snd_ctl_elem_value_set_integer64(control, i, value);
+ break;
+ case SND_CTL_ELEM_TYPE_ENUMERATED:
+ snd_ctl_elem_value_set_enumerated(control, i, value);
+ break;
+ case SND_CTL_ELEM_TYPE_BYTES:
+ snd_ctl_elem_value_set_byte(control, i, value);
+ break;
+ default:
+ break;
+ }
+
+ ret = snd_ctl_elem_write(mHandle, control);
+ return (ret < 0) ? BAD_VALUE : NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
}; // namespace android