alsa amixer 使用介绍

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;
}

 

 

你可能感兴趣的:(alsa)