I can't seem to be able to set the volume in dB on my Machine.
I am running a Ubuntu 13.04 System in a VirtualBox (for development).
I followed these instructions to set the volume as scalar and to control the mute state and everything works just fine.
But when I try to set it in dB with this function
snd_mixer_selem_set_playback_dB_all(elem, volume, 0)
or with that function
snd_mixer_selem_set_playback_dB(elem, chn, volume, 0)
it always fails with the error code -22 (Invalid argument)
Before you ask: I already tried out a wide range of volume levels to set (from -20000 to 20000) and I also changed the last parameter to the three defined values [-1, 0, 1]
Here is my complete code for testing right now:
#include <alsa/asoundlib.h>
#include <stdbool.h>
#include <stdlib.h>
void SetAlsaMasterVolume(long volume) {
long min, max;
snd_mixer_t *handle;
snd_mixer_selem_id_t *sid;
const char *card = "default";
const char *selem_name = "Master";
int x, mute_state;
long i;
snd_mixer_open(&handle, 0);
snd_mixer_attach(handle, card);
snd_mixer_selem_register(handle, NULL, NULL);
snd_mixer_load(handle);
snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_id_set_index(sid, 0);
snd_mixer_selem_id_set_name(sid, selem_name);
snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);
//snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
//snd_mixer_selem_set_playback_volume_all(elem, volume * max / 100);
snd_mixer_selem_get_playback_dB_range(elem, &min, &max);
printf("min: %ld, max: %ld\n", min, max);
snd_mixer_selem_channel_id_t chn;
for (chn = 0; chn < 32; chn++) {
for (i = -1000; i <= 1000; i++)
if (x = snd_mixer_selem_set_playback_dB(elem, chn, i, 0)) {
;//printf("%d: %d %s\n", chn, x, snd_strerror(x));
} else {
printf("Volume successfully set in dB!\n");
}
}
if (snd_mixer_selem_has_playback_switch(elem)) {
snd_mixer_selem_set_playback_switch_all(elem, true);
snd_mixer_selem_get_playback_switch(elem, 0, &mute_state);
if (!mute_state) {
printf("System Muted.\n");
} else {
printf("System unmuted.\n");
}
}
snd_mixer_close(handle);
}
int main() {
SetAlsaMasterVolume(100);
return 0;
}
As you see I in this example I try to set every channel by myself, it's the same thing "snd_mixer_selem_set_playback_dB_all" does, but I wanted to try it to see if I get different results.
The output of this example looks like this:
min: 15774463, max: 191
System unmuted.
Befor I widened the range of dB values I tested the output was:
min: 1, max: 191
Maybe I am missing something here... I hope you can help me out!
edit:
To compile this script I use the following command:
gcc test.c -lasound -o test