alsa-utils 提供的工具中,arecord 可以用来录音,aplay 可以用来播放,amixer 可以用来控制音量、增益等。
/ # amixer controls
numid=34,iface=MIXER,name='Master Switch'
numid=35,iface=MIXER,name='Master Switch X'
numid=32,iface=MIXER,name='Master Volume'
numid=33,iface=MIXER,name='Master Volume X'
...
可以通过amixer controls 列出alsa下面的控制节点
/ # amixer cget name='Master Volume'
numid=32,iface=MIXER,name='Master Volume'
; type=INTEGER,access=rw------,values=1,min=0,max=100,step=0
: values=100
要查看Master Volume 这个节点更详细的信息,可以输入 amixer cget name='节点名称'
这个节点名称是相关驱动注册,添加到alsa驱动框架中生成的,并不一定是固定的名称。
/ # amixer cset name='Master Volume' 80
numid=32,iface=MIXER,name='Master Volume'
; type=INTEGER,access=rw------,values=1,min=0,max=100,step=0
: values=80
通过amixer cset 命令可以修改节点的值,amixer cset name='节点名称' (新的值)
通过代码实现如下
#include
#include
#include
#include
#include
#include
#include
#include
#define ALSA_MIXER_NAME "default"
#define ALSA_ELEM_NAME "Master Volume"
static snd_mixer_t *mixer = NULL;
static snd_mixer_elem_t *elem=NULL;
static int alsa_mixer_init()
{
//1. 打开mixer
if (snd_mixer_open(&mixer, 0)<0){
printf("snd_mixer_open fail.\n");
return -1;
}
// 2. attach HCTL to open mixer
if (snd_mixer_attach(mixer, ALSA_MIXER_NAME) < 0){
printf("snd_mixer_attach fail.\n");
goto mixer_fail;
}
// 3.register mixer
if (snd_mixer_selem_register(mixer, NULL, NULL) < 0){
printf("snd_mixer_attach fail.\n");
goto mixer_fail;
}
// 4. load mixer
if (snd_mixer_load(mixer) < 0) {
printf("snd_mixer_load fail.\n");
goto mixer_fail;
}
// 5. find the elem
for (elem = snd_mixer_first_elem(mixer); elem;elem = snd_mixer_elem_next(elem))
{
if (snd_mixer_elem_get_type(elem)==SND_MIXER_ELEM_SIMPLE&&snd_mixer_selem_is_active(elem))
{
//printf("mixer elem name is %s.\n",snd_mixer_selem_get_name(elem));
if (strcmp(snd_mixer_selem_get_name(elem), ALSA_ELEM_NAME) == 0)
{
printf("found mixer elem, name is %s.\n",ALSA_ELEM_NAME);
long int alsa_left=0,alsa_right=0;
//snd_mixer_selem_set_playback_volume_range(elem, 0, 1000);
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &alsa_left);
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, &alsa_right);
//snd_mixer_selem_set_playback_volume_range(elem, AUDIO_MIN_VOLUME, AUDIO_MAX_VOLUME);
//snd_mixer_selem_set_playback_volume_all(elem, mix_vol);
printf("alsa_left is %ld,alsa_right is %ld.\n",alsa_left,alsa_right);
return 0;
}
}
}
mixer_fail:
snd_mixer_close(mixer);
mixer=NULL;
return -1;
}
static int set_master_volume(int vol)
{
if(mixer != NULL && elem != NULL)
{
return snd_mixer_selem_set_playback_volume_all(elem, vol);
}
return -1;
}
static int alsa_mixer_uninit()
{
if(mixer != NULL)
{
snd_mixer_close(mixer);
mixer=NULL;
return 0;
}
return -1;
}
另一种实现方式
#include
#include
#include
#include
#include
#include
#include
#include
#define ALSA_HCTL_NAME "default"
#define ALSA_HCTL_ELEM_NAME "name='Master Volume'"
static snd_hctl_t *pt_hctl=NULL;
static snd_hctl_elem_t *pt_helem=NULL;
static int alsa_ctrl_init()
{
snd_ctl_elem_id_t *pt_id;
snd_ctl_elem_id_alloca(&pt_id);
//1. open hctl
if(snd_hctl_open(&pt_hctl, ALSA_HCTL_NAME, 0)<0)
{
printf("snd_hctl_open fail.\n");
return -1;
}
//2. load hctl
if(snd_hctl_load(pt_hctl)<0)
{
printf("snd_hctl_load fail.\n");
goto hctl_fail;
}
//3. parse ctl elem
if(snd_ctl_ascii_elem_id_parse(pt_id, ALSA_HCTL_ELEM_NAME)<0)
{
printf("snd_ctl_ascii_elem_id_parse fail.\n");
goto hctl_fail;
}
//4. find hctl elem
pt_helem = snd_hctl_find_elem(pt_hctl, pt_id);
if (!pt_helem)
{
printf("snd_hctl_find_elem fail.\n");
goto hctl_fail;
}
return 0;
hctl_fail:
snd_hctl_close(pt_hctl);
pt_hctl=NULL;
return -1;
}
static int set_master_volume(int vol)
{
int ret = -1;
snd_ctl_elem_value_t *pt_value;
snd_ctl_elem_value_alloca(&pt_value);
//5. read hctl elem
if(snd_hctl_elem_read(pt_helem, pt_value)<0)
{
printf("snd_hctl_elem_read fail.\n");
goto set_volume_end;
}
//get elem value
long volume=snd_ctl_elem_value_get_integer(pt_value, 0);
printf("snd_ctl_elem_value_get_integer volume = %ld.\n",volume);
//set elem value
snd_ctl_elem_value_set_integer(pt_value, 0, vol);
//6 write hctl elem
if(snd_hctl_elem_write(pt_helem, pt_value))
{
printf("snd_hctl_elem_write fail.\n");
goto set_volume_end;
}
printf("set_master_volume volume = %d.\n",vol);
ret = 0;
set_volume_end:
snd_ctl_elem_value_free(pt_value);
ret;
}
static int alsa_ctrl_uninit()
{
if(pt_hctl)
{
snd_hctl_close(pt_hctl);
pt_hctl = NULL;
return 0;
}
return -1;
}