使用asoundlib api调节音量大小. 做成命令行的形式.
使用方法
Usage: ./alsa_demo get
./alsa_demo set volmue <-[0~99]
代码
#include <unistd.h>
#include <fcntl.h>
#include <alsa/asoundlib.h>
#define VOLUME_BOUND 100
typedef enum {
AUDIO_VOLUME_SET,
AUDIO_VOLUME_GET,
} audio_volume_action;
/*
Drawbacks. Sets volume on both channels but gets volume on one. Can be easily adapted.
*/
int audio_volume(audio_volume_action action, long* outvol)
{
snd_mixer_t* handle;
snd_mixer_elem_t* elem;
snd_mixer_selem_id_t* sid;
static const char* mix_name = "Playback";//改成你的mixer选项名,跟alsamixer里,音量选择项的名字保持一致.
static const char* card = "default";
static int mix_index = 0;
long pmin, pmax;
long get_vol, set_vol;
float f_multi;
int ret;
snd_mixer_selem_id_alloca(&sid);
//sets simple-mixer index and name
snd_mixer_selem_id_set_index(sid, mix_index);
snd_mixer_selem_id_set_name(sid, mix_name);
if ((snd_mixer_open(&handle, 0)) < 0)
return -1;
if ((snd_mixer_attach(handle, card)) < 0) {
snd_mixer_close(handle);
return -2;
}
if ((snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
snd_mixer_close(handle);
return -3;
}
ret = snd_mixer_load(handle);
if (ret < 0) {
snd_mixer_close(handle);
return -4;
}
elem = snd_mixer_find_selem(handle, sid);
if (!elem) {
snd_mixer_close(handle);
return -5;
}
long minv, maxv;
snd_mixer_selem_get_playback_volume_range (elem, &minv, &maxv);
fprintf(stderr, "Volume range <%i,%i>\n", minv, maxv);
if(action == AUDIO_VOLUME_GET) {
if(snd_mixer_selem_get_playback_volume(elem, 0, outvol) < 0) {
snd_mixer_close(handle);
return -6;
}
fprintf(stderr, "Get volume %i with status %i\n", *outvol, ret);
/* make the value bound to 100 */
*outvol -= minv;
maxv -= minv;
minv = 0;
*outvol = (int)(100 * (float)(*outvol) / maxv + 0.5); // make the value bound from 0 to 100
//o = 100 *o /255
}
else if(action == AUDIO_VOLUME_SET) {
if(*outvol < 0 || *outvol > VOLUME_BOUND) // out of bounds
return -7;
*outvol = (*outvol * (maxv - minv) / (100)) + minv;
//o = o * 255 /100
if(snd_mixer_selem_set_playback_volume(elem, 0, *outvol) < 0) {
snd_mixer_close(handle);
return -8;
}
if(snd_mixer_selem_set_playback_volume(elem, 1, *outvol) < 0) {
snd_mixer_close(handle);
return -9;
}
fprintf(stderr, "volme_set:Set volume %i with status %i\n", *outvol, ret);
}
snd_mixer_close(handle);
return 0;
}
void usage(void)
{
printf("Usage: ./alsa_demo get\n");
printf(" ./alsa_demo set volmue <-[0~99]\n");
}
int main(int argc,char* argv[])
{
long vol = -1;
int i;
if(argc <= 1)
goto err;
if(!strcmp(argv[1],"get")) { //get volume
if(argc == 2) {
printf("Ret %i\n", audio_volume(AUDIO_VOLUME_GET, &vol));
printf("volme_get: playback volume is %i\n", vol);
} else
goto err;
} else if (!strcmp(argv[1],"set")){ //set volume
if(argc == 3) {
vol = atoi(argv[2]);
if(vol >= 0 && vol < 100)
printf("Ret %i\n", audio_volume(AUDIO_VOLUME_SET, &vol));
else
goto err;
} else
goto err;
} else
goto err;
return 0;
err:
usage();
return -1;
}
编译例子
$CC alsa_demo.c -o alsa_demo -lasound