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

如何使用C#在Linux中使用ALSA获取和设置卷?,c#,linux,gnome,alsa,C#,Linux,Gnome,Alsa,我想用C代码获取Linux的系统卷。如何做到这一点 额外信息: -->是否有我可以使用的库/dll -->我遇到过阿尔萨夏普,但我没有发现任何关于音量的功能 -->我遇到过C代码,但我不熟悉如何在C中使用它 迟到总比不迟到好,但我在设置基于RPi的互联网广播时遇到了这一点,下面的代码也适用于我,你也可以找到 它是以和为基础的https://github.com/atsushieno. 注意:您可能需要尝试使用“card”和“selemName”参数 using System; using Sys

我想用C代码获取Linux的系统卷。如何做到这一点

额外信息:

-->是否有我可以使用的库/dll

-->我遇到过阿尔萨夏普,但我没有发现任何关于音量的功能


-->我遇到过C代码,但我不熟悉如何在C中使用它

迟到总比不迟到好,但我在设置基于RPi的互联网广播时遇到了这一点,下面的代码也适用于我,你也可以找到

它是以和为基础的https://github.com/atsushieno.

注意:您可能需要尝试使用“card”和“selemName”参数

using System;
using System.Runtime.InteropServices;

namespace Alsa
{
    public sealed class VolumeControl : IDisposable
    {
        private readonly long _min;
        private readonly long _max;
        private readonly IntPtr _sid;
        private readonly IntPtr _selem;
        private readonly IntPtr _handle;
        private const string LibraryName = "libasound";

        public VolumeControl(string card = "default", string selemName = "PCM")
        {
            snd_mixer_open(ref _handle, 0);
            snd_mixer_attach(_handle, card);
            snd_mixer_selem_register(_handle, default, default);
            snd_mixer_load(_handle);

            snd_mixer_selem_id_malloc(ref _sid);
            snd_mixer_selem_id_set_index(_sid, 0);
            snd_mixer_selem_id_set_name(_sid, selemName);
            _selem = snd_mixer_find_selem(_handle, _sid);

            snd_mixer_selem_get_playback_volume_range(_selem, ref _min, ref _max);
        }

        public void SetVolumePercent(int volume)
        {
            snd_mixer_selem_set_playback_volume_all(_selem, (int)(volume * _max / 100));
        }

        public void Dispose()
        {
            ReleaseUnmanagedResources();
            GC.SuppressFinalize(this);
        }

        private void ReleaseUnmanagedResources()
        {
            snd_mixer_selem_id_free(_sid);
            snd_mixer_close(_handle);
        }

        ~AlsaSoundOutput()
        {
            ReleaseUnmanagedResources();
        }

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_open(ref IntPtr mixer, int mode);

        [DllImport(LibraryName, CharSet = CharSet.Ansi)]
        internal static extern int snd_mixer_attach(IntPtr mixer, [MarshalAs(UnmanagedType.LPStr)] string name);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_selem_register(IntPtr mixer, IntPtr options, IntPtr classp);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_load(IntPtr mixer);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_selem_id_malloc(ref IntPtr selem);

        [DllImport(LibraryName)]
        internal static extern void snd_mixer_selem_id_set_index(IntPtr selem, uint val);

        [DllImport(LibraryName, CharSet = CharSet.Ansi)]
        internal static extern void snd_mixer_selem_id_set_name(IntPtr selem, [MarshalAs(UnmanagedType.LPStr)] string value);

        [DllImport(LibraryName)]
        internal static extern IntPtr snd_mixer_find_selem(IntPtr mixer, IntPtr selem);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_selem_get_playback_volume_range(IntPtr selem, ref long min, ref long max);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_selem_set_playback_volume_all(IntPtr selem, int value);

        [DllImport(LibraryName)]
        internal static extern void snd_mixer_selem_id_free(IntPtr selem);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_close(IntPtr mixer);
    }
}

迟做总比不做强,但我在建立一个基于RPi的网络广播时遇到了这个问题,下面的代码,你也可以找到,对我来说很有用

它是以和为基础的https://github.com/atsushieno.

注意:您可能需要尝试使用“card”和“selemName”参数

using System;
using System.Runtime.InteropServices;

namespace Alsa
{
    public sealed class VolumeControl : IDisposable
    {
        private readonly long _min;
        private readonly long _max;
        private readonly IntPtr _sid;
        private readonly IntPtr _selem;
        private readonly IntPtr _handle;
        private const string LibraryName = "libasound";

        public VolumeControl(string card = "default", string selemName = "PCM")
        {
            snd_mixer_open(ref _handle, 0);
            snd_mixer_attach(_handle, card);
            snd_mixer_selem_register(_handle, default, default);
            snd_mixer_load(_handle);

            snd_mixer_selem_id_malloc(ref _sid);
            snd_mixer_selem_id_set_index(_sid, 0);
            snd_mixer_selem_id_set_name(_sid, selemName);
            _selem = snd_mixer_find_selem(_handle, _sid);

            snd_mixer_selem_get_playback_volume_range(_selem, ref _min, ref _max);
        }

        public void SetVolumePercent(int volume)
        {
            snd_mixer_selem_set_playback_volume_all(_selem, (int)(volume * _max / 100));
        }

        public void Dispose()
        {
            ReleaseUnmanagedResources();
            GC.SuppressFinalize(this);
        }

        private void ReleaseUnmanagedResources()
        {
            snd_mixer_selem_id_free(_sid);
            snd_mixer_close(_handle);
        }

        ~AlsaSoundOutput()
        {
            ReleaseUnmanagedResources();
        }

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_open(ref IntPtr mixer, int mode);

        [DllImport(LibraryName, CharSet = CharSet.Ansi)]
        internal static extern int snd_mixer_attach(IntPtr mixer, [MarshalAs(UnmanagedType.LPStr)] string name);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_selem_register(IntPtr mixer, IntPtr options, IntPtr classp);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_load(IntPtr mixer);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_selem_id_malloc(ref IntPtr selem);

        [DllImport(LibraryName)]
        internal static extern void snd_mixer_selem_id_set_index(IntPtr selem, uint val);

        [DllImport(LibraryName, CharSet = CharSet.Ansi)]
        internal static extern void snd_mixer_selem_id_set_name(IntPtr selem, [MarshalAs(UnmanagedType.LPStr)] string value);

        [DllImport(LibraryName)]
        internal static extern IntPtr snd_mixer_find_selem(IntPtr mixer, IntPtr selem);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_selem_get_playback_volume_range(IntPtr selem, ref long min, ref long max);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_selem_set_playback_volume_all(IntPtr selem, int value);

        [DllImport(LibraryName)]
        internal static extern void snd_mixer_selem_id_free(IntPtr selem);

        [DllImport(LibraryName)]
        internal static extern int snd_mixer_close(IntPtr mixer);
    }
}

您是否检查过与ALSA相关的.net包装器?谷歌搜索结果显示我声称支持ALSA作为后端。是的,我已经检查过了。但是它们没有任何我可以使用的音量函数。例如,在Alsa Sharp和SoundIOSharp中,他们都导入了一些“设置音量”功能。但我在它们各自的源代码中没有看到任何C#实现。因此,我无法使用它们。我没有测试也没有下载API,但看起来API具有返回卷的属性。我也不确定如何使用该属性,SoundIOOutStream的构造函数需要一个参数,我不确定如何使用该参数。内部SoundIOOutStream(指针句柄)是否检查了与ALSA相关的.net包装?谷歌搜索结果显示我声称支持ALSA作为后端。是的,我已经检查过了。但是它们没有任何我可以使用的音量函数。例如,在Alsa Sharp和SoundIOSharp中,他们都导入了一些“设置音量”功能。但我在它们各自的源代码中没有看到任何C#实现。因此,我无法使用它们。我没有测试也没有下载API,但看起来API具有返回卷的属性。我也不确定如何使用该属性,SoundIOOutStream的构造函数需要一个参数,我不确定如何使用该参数。内部声音超流(指针手柄)