Reputation: 197
I have an app which is using Alsa to play sounds. Below I show fragments of my code. The problem is that if my software is run as a systemd service, the range in the stVolume method is between 0 and 31. When I run my software as a standard application from the command line, the range is between 0 and 65536. In the first scenario the sound is very distorted and loud, I hear noise. It is much better in the second scenario. What is the reason? Why the same code run in a different way seems to use Alsa/sound card differently? Why Alsa is returning different range in both cases?
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);
}
where mMixer is a following struct:
struct {
snd_mixer_t *handle;
snd_mixer_selem_id_t *sid;
snd_mixer_elem_t *slider;
} mMixer;
and mCardName and mMixerName are:
const char *mCardName = "default";
const char *mMixerName = "Master";
When I want to play sound, I invoke the following method:
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());
}
}
and then I set the volume:
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);
}
Upvotes: 0
Views: 199