使用asoundlib 调节音量大小

使用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

猜你喜欢

转载自blog.csdn.net/a827143452/article/details/89248136