summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean McNeil <sean.mcneil@windriver.com>2009-04-16 06:07:30 +0700
committerSean McNeil <sean.mcneil@windriver.com>2009-04-16 06:07:30 +0700
commit0c6fdabac66a07a37a14d87022aff3dfb306218b (patch)
tree30d698a68ec33c5274a3aff6ea626dd5e4f625dc
parentd9ca3222cff122312af6dd329063dd8fd6f40dcf (diff)
downloadalsa_sound-0c6fdabac66a07a37a14d87022aff3dfb306218b.tar.gz
Add new generic ALSA control interface
-rw-r--r--AudioHardwareALSA.cpp118
-rw-r--r--AudioHardwareALSA.h13
2 files changed, 131 insertions, 0 deletions
diff --git a/AudioHardwareALSA.cpp b/AudioHardwareALSA.cpp
index bce67ef..27ca979 100644
--- a/AudioHardwareALSA.cpp
+++ b/AudioHardwareALSA.cpp
@@ -1401,4 +1401,122 @@ status_t ALSAMixer::getPlaybackMuteState(uint32_t device, bool *state)
// ----------------------------------------------------------------------------
+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
diff --git a/AudioHardwareALSA.h b/AudioHardwareALSA.h
index 56045ff..0568a1e 100644
--- a/AudioHardwareALSA.h
+++ b/AudioHardwareALSA.h
@@ -53,6 +53,19 @@ namespace android
snd_mixer_t *mMixer[SND_PCM_STREAM_LAST+1];
};
+ class ALSAControl
+ {
+ public:
+ ALSAControl(const char *device = "default");
+ virtual ~ALSAControl();
+
+ status_t get(const char *name, unsigned int &value, int index = 0);
+ status_t set(const char *name, unsigned int value, int index = -1);
+
+ private:
+ snd_ctl_t *mHandle;
+ };
+
class ALSAStreamOps
{
public: