我有一个使用 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);
}