在 Linux 中用 C 语言获取主音量

     2023-03-14     14

关键词:

【中文标题】在 Linux 中用 C 语言获取主音量【英文标题】:Get master sound volume in C in Linux 【发布时间】:2011-12-01 05:44:50 【问题描述】:

我正在尝试检索(可能稍后设置)Linux 中的主音量。我正在使用 PulseAudio,但理想情况下它也适用于 ALSA。

我发现this 关于如何设置音量的帖子非常有用,并且从中我能够推断出 snd_mixer_selem_get_playback_volume() 的存在以检索当前设置。但是在我的系统上,这似乎给了我错误的读数 - 混音器程序显示 100%,最高约为 66%。

如果我打开 pavucontrol,我可以看到这个输出设备的音量与我从这里得到的读数相匹配,所以我认为它给了我硬件音量设置,而不是我想要的全局主音量。

【问题讨论】:

【参考方案1】:

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, 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 = 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, 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, "Set volume %i with status %i\n", *outvol, ret);
    

    snd_mixer_close(handle);
    return 0;
#endif
    

int main(void)

    long vol = -1;
    printf("Ret %i\n", audio_volume(AUDIO_VOLUME_GET, &vol));
    printf("Master volume is %i\n", vol);

    vol = 100;
    printf("Ret %i\n", audio_volume(AUDIO_VOLUME_SET, &vol));

    return 0;

【讨论】:

除了额外的错误检查之外,这似乎与我链接的代码做同样的事情。 嗯,这对我有用,很抱歉它不适合你。我不使用更高级的 PulseAudio 功能。我认为 PulseAudio 允许在内部增加超过 100% 的音量(将样本乘以 >1),所以也许你应该看看 PulseAudio API 来控制音量? RushPL 如何分别改变左右声道的音量。我曾尝试分别为 0 和 1 调用“snd_mixer_selem_set_playback_volume”,但更改了整个主音量。 任何 PulseAudio 示例来改变左右声道音量变化? 所以您知道,在任何 Stack Exchange 站点上发布的任何和所有代码都会根据他们选择的许可自动获得许可,而不是您的许可。显然,您可以重新许可它,但 Stack Exchange 上的特定来源随该许可一起提供。

在 c# 中获取主音量

】在c#中获取主音量【英文标题】:GetMasterSoundVolumeinc#【发布时间】:2011-02-0120:07:22【问题描述】:我需要获取当前输出到声卡的音量。有什么想法吗?【问题讨论】:另一个解决方案是来自代码项目的这篇文章(也是):VolumeM... 查看详情

如何在 windows xp 中获取主音量?

】如何在windowsxp中获取主音量?【英文标题】:Howtogetthemastervolumeinwindowsxp?【发布时间】:2011-05-2903:27:02【问题描述】:在WindowsXP中,使用Delphi,如何获取主卷?我知道我可以使用keybd_event(VK_VOLUME_UP,1,0,0);和keybd_event(VK_VOLUME_DOWN,1,... 查看详情

如何使用 C# 使用 ALSA 在 Linux 中获取和设置音量?

】如何使用C#使用ALSA在Linux中获取和设置音量?【英文标题】:HowtogetandsetvolumeinLinuxusingALSAusingC#?【发布时间】:2020-01-1501:06:35【问题描述】:我想使用C#代码获取Linux的系统卷。如何做到这一点?额外信息:-->有没有我可以使... 查看详情

使用 Python 在 linux 中获取系统音量(声级)

】使用Python在linux中获取系统音量(声级)【英文标题】:Getsystemvolume(Soundlevel)inlinuxusingPython【发布时间】:2012-07-1902:33:32【问题描述】:我正在使用Fedora16并在python2.7中修改程序。如何获取系统音量(声级)?【问题讨论】:... 查看详情

c#win7如何获得系统主音量只需知道主音大小无需修改

...好的方法,可以使用API进行主音量调节,但是不知道怎么获取系统当前的主音 查看详情

从 C 代码设置 ALSA 主音量

】从C代码设置ALSA主音量【英文标题】:SetALSAmastervolumefromCcode【发布时间】:2011-10-1020:48:50【问题描述】:我一直在寻找一个简单的C代码示例来设置ALSA混音器的主音量,但找不到任何简单的东西来完成这个所谓的常见操作。我... 查看详情

从 C 代码中以 dB 为单位设置 ALSA 主音量

】从C代码中以dB为单位设置ALSA主音量【英文标题】:SetALSAmastervolumeindBfromCcode【发布时间】:2013-10-2915:20:57【问题描述】:我似乎无法在我的机器上以dB为单位设置音量。我在VirtualBox中运行Ubuntu13.04系统(用于开发)。我按照这... 查看详情

c语言如何在子函数中对主函数中的二维数组值进行修改?二维数组已经在主函数中用动态数组分配了空间。

参考技术A用指针做函数参数可以实现!追问这个我也知道,问题是我怎么改都不对,要不我也不会到这来问了。您有没有源码示例一下?谢谢! 参考技术B用数组时,必须要知道二维数组的后一个维度,否则无法正确修改,比如... 查看详情

linux中用c语言编写完模块后怎么编写makefile文件?用到啥命令?以啥格式编写?

viMakefile#打开vi编辑器在编辑器里输入以下内容:#当只有一个文件需要编译的时候finame:filename.c#冒号前面是要编译成的目标文件(可以任意命名),后面是你编写的C文件gcc-ofilenamefilename.c#gcc前面是按Tab制表符#filename:filename.c是指filen... 查看详情

在 Linux 上使用纯 C 项目中用 C++ 编写的库?

】在Linux上使用纯C项目中用C++编写的库?【英文标题】:UsingalibrarywritteninC++fromapureCprojectonLinux?【发布时间】:2011-09-3011:30:26【问题描述】:找到这个声明overatPSE:(引用Bob)我在Windows和MacOS上最喜欢的技巧之一在Linux上不起作用... 查看详情

在 Windows 中用 C 语言计算百分比

】在Windows中用C语言计算百分比【英文标题】:CalculatingpercentageinCinWindows【发布时间】:2013-04-1903:45:40【问题描述】:我有以下代码行来计算计数/总数的百分比。在MicrosoftVisualC++2005中printf("Count=%lu(%.2lf%%)\\n",count,(double)count/(double)... 查看详情

Pygame - 永久调整主音量

】Pygame-永久调整主音量【英文标题】:Pygame-permantlyadjustingmastervolume【发布时间】:2014-07-2117:36:03【问题描述】:我有一个在按键上播放正弦波音符的程序。这个想法是模拟仪器。我添加了一些代码来调整音量,但是每次播放新... 查看详情

在 iPhone 上获取当前系统音量

】在iPhone上获取当前系统音量【英文标题】:getcurrentsystemvolumeleveloniPhone【发布时间】:2009-02-2107:53:04【问题描述】:有什么方法可以让我在iPhone上获得当前的系统音量级别?我在想也许有办法制作MPVolumeView并从中获得价值。【... 查看详情

无法从可可objective-c的任何音频设备获取输出音量

】无法从可可objective-c的任何音频设备获取输出音量【英文标题】:Cannotgetoutputvolumefromanyaudiodevicesfromcocoaobjective-c【发布时间】:2012-04-0318:05:32【问题描述】:我正在尝试在macosx应用程序中实现音量控制。当我运行代码循环安装... 查看详情

如何在主函数中获取“语言代码”?

】如何在主函数中获取“语言代码”?【英文标题】:HowcanIget\'languagecode\'inmainfunction?【发布时间】:2021-04-1923:26:41【问题描述】:如何在主函数中获取语言代码?我想为本地化推送通知编写语言代码?【问题讨论】:您反对在... 查看详情

如何在 Linux (Ubuntu) 中输出频率 1kHz 和功率/音量 = 60%?

】如何在Linux(Ubuntu)中输出频率1kHz和功率/音量=60%?【英文标题】:Howtooutputafrequency1kHzandpower/volume=60%inLinux(Ubuntu)?【发布时间】:2009-12-1105:33:22【问题描述】:我需要C/C++中的示例代码。谢谢!【问题讨论】:您使用哪个API来控制... 查看详情

关于在linux下用gcc编译头文件

有node.hprepare.hlist.hfile.h这四个头文件,prepare.h中用到了node.h,list.h中用到了preapre.h,file.h中用到了list.h,怎么用gcc对这四个头文件进行编译。首先,确定你的头文件都用宏隔开了,防止了重复定义。例如,在file.h中的开头就是#ifndef... 查看详情

在 C# 中将主音量从 XP 更改为 Windows 8

】在C#中将主音量从XP更改为Windows8【英文标题】:ChangemasteraudiovolumefromXPtoWindows8inC#【发布时间】:2013-03-0614:46:55【问题描述】:我需要一些通用方法来使用C#将主音量从WindowsXP更改为Windows8,因为我的应用程序将在这些操作系统... 查看详情