在Linux中获取C中的主音量
发布时间:2020-12-14 00:59:47 所属栏目:Linux 来源:网络整理
导读:我正试图在 Linux中检索(可能稍后设置)主音量.我正在使用PulseAudio,但理想情况下它也适用于ALSA. 我找到了关于如何设置音量的this非常有用的帖子,从中我能够推断出snd_mixer_selem_get_playback_volume()的存在以检索当前设置.然而,在我的系统上,这似乎给了
我正试图在
Linux中检索(可能稍后设置)主音量.我正在使用PulseAudio,但理想情况下它也适用于ALSA.
我找到了关于如何设置音量的this非常有用的帖子,从中我能够推断出snd_mixer_selem_get_playback_volume()的存在以检索当前设置.然而,在我的系统上,这似乎给了我错误的读数 – 混音器程序显示100%,最高约66%. 如果我打开pavucontrol,我可以看到这个输出设备的音量与我从这里得到的读数相匹配,所以我假设它给了我硬件音量设置,而不是我想要的全局主音量. 解决方法
使用gcc audio_volume.c -o audio_volume -lasound或使用gcc audio_volume.c -o audio_volume_oss -DOSSCONTROL编译以下代码. OSS版本写得很粗糙,并没有给出精确的结果.在我的系统中将音量设置为100可设置97%的音量. ALSA版本适用于我和openSUSE中的PulseAudio.需要一些清理和爱,但我希望它是你需要的,我允许在
WTFPL license上使用它.
#include <unistd.h> #include <fcntl.h> #ifdef OSSCONTROL #define MIXER_DEV "/dev/dsp" #include <sys/soundcard.h> #include <sys/ioctl.h> #include <stdio.h> #else #include <alsa/asoundlib.h> #endif 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) { #ifdef OSSCONTROL int ret = 0; int fd,devs; if ((fd = open(MIXER_DEV,O_WRONLY)) > 0) { if(action == AUDIO_VOLUME_SET) { if(*outvol < 0 || *outvol > 100) return -2; *outvol = (*outvol << 8) | *outvol; ioctl(fd,SOUND_MIXER_WRITE_VOLUME,outvol); } else if(action == AUDIO_VOLUME_GET) { ioctl(fd,SOUND_MIXER_READ_VOLUME,outvol); *outvol = *outvol & 0xff; } close(fd); return 0; } return -1;; #else snd_mixer_t* handle; snd_mixer_elem_t* elem; snd_mixer_selem_id_t* sid; static const char* mix_name = "Master"; static const char* card = "default"; static int mix_index = 0; long pmin,pmax; long get_vol,set_vol; float f_multi; 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,outvol) < 0) { snd_mixer_close(handle); return -6; } fprintf(stderr,"Get volume %i with status %in",*outvol,ret); /* make the value bound to 100 */ *outvol -= minv; maxv -= minv; minv = 0; *outvol = 100 * (*outvol) / maxv; // make the value bound from 0 to 100 } else if(action == AUDIO_VOLUME_SET) { if(*outvol < 0 || *outvol > VOLUME_BOUND) // out of bounds return -7; *outvol = (*outvol * (maxv - minv) / (100-1)) + minv; if(snd_mixer_selem_set_playback_volume(elem,*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,"Set volume %i with status %in",ret); } snd_mixer_close(handle); return 0; #endif } int main(void) { long vol = -1; printf("Ret %in",audio_volume(AUDIO_VOLUME_GET,&vol)); printf("Master volume is %in",vol); vol = 100; printf("Ret %in",audio_volume(AUDIO_VOLUME_SET,&vol)); return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |