0

我有一个使用 Alsa 播放声音的应用程序。下面我展示了我的代码片段。问题是,如果我的软件作为 systemd 服务运行,stVolume 方法的范围在 0 到 31 之间。当我从命令行将软件作为标准应用程序运行时,范围在 0 到 65536 之间。第一种情况声音非常失真且响亮,我听到噪音。在第二种情况下要好得多。是什么原因?为什么相同的代码以不同的方式运行似乎以不同的方式使用 Alsa/声卡?为什么 Alsa 在这两种情况下都返回不同的范围?

void init() {
    snd_mixer_open(&mMixer.handle, 0);
    snd_mixer_attach(mMixer.handle, mCardName);
    snd_mixer_selem_register(mMixer.handle, NULL, NULL);
    snd_mixer_load(mMixer.handle);

    snd_mixer_selem_id_alloca(&mMixer.sid);
    snd_mixer_selem_id_set_index(mMixer.sid, 0);
    snd_mixer_selem_id_set_name(mMixer.sid, mMixerName);
    mMixer.slider = snd_mixer_find_selem(mMixer.handle, mMixer.sid);
}

其中 mMixer 是以下结构:

struct {
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;
    snd_mixer_elem_t *slider;
} mMixer;

mCardName 和 mMixerName 是:

const char *mCardName = "default";
const char *mMixerName = "Master";

当我想播放声音时,我调用以下方法:

void on() {
    try {
        // open audio device
        int err = snd_pcm_open(&mHandle, mCardName,
            SND_PCM_STREAM_PLAYBACK,
            SND_PCM_NONBLOCK);
        
        if (err < 0)
            throw std::runtime_error(snd_strerror(err));

        // configure audio
        g_assert_nonnull(mHandle);

        err = snd_pcm_set_params(mHandle,
            SND_PCM_FORMAT_U8,
            SND_PCM_ACCESS_RW_INTERLEAVED,
            1,         // channels
            SAMPLE_RATE,     // sample rate
            1,         // soft resample allowed
            500000);   // latency (in us)

        if (err < 0)
            throw std::runtime_error(snd_strerror(err));
    } catch(std::runtime_error &e) {
        g_printerr("Can't configure audio: %s\n", e.what());
    }
}

然后我设置音量:

void setVolume(unsigned volume) {
    long min = 0, max = 0;      // NOLINT (type required by ALSA
    snd_mixer_selem_get_playback_volume_range(mMixer.slider, &min, &max);
    snd_mixer_selem_set_playback_volume_all(mMixer.slider, volume * max / 100);

    g_warning("FHR probe volume %ld. Min: %ld, Max: %ld", volume * max / 100, min, max);
}
4

0 回答 0