0

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);
}
Jacek
  • 187
  • 2
  • 13
  • `The problem is that if my software is run as a systemd service.... When I run my software as a standard application` Hard to say without actually having the code for the two versions... you need a minimal example, or something more to work with. – UmNyobe Sep 08 '20 at 08:58
  • The code is the same. The difference is how it is run. app.service file put in /etc/systemd/system looks like this: – Jacek Sep 08 '20 at 09:00
  • app.service file put in /etc/systemd/system looks like this: ``` [Unit] Description=app After=sound.target [Service] Type=dbus BusName=com.app.bus ExecStart=/usr/bin/app Restart=always [Install] WantedBy=multi-user.target ``` – Jacek Sep 08 '20 at 09:05
  • look at https://unix.stackexchange.com/questions/339638/difference-between-systemd-and-terminal-starting-program on some differences between the two environments. It is possible that something on your code (here or the non shown part) is incorrect, but work on one environment. It is quite possible that an alsa command in the init is failing, but you don't check the return status. It is also possible that you just need to configure the service environment to make it work. To be short, start by making sure all the commands in the init are successful in both. – UmNyobe Sep 08 '20 at 10:21
  • I've checked. All alsa commands return 0 no matter which environment is used. I'll dig into the link you provided. For now it seems that both environments use different mixer/whatever. There is one thing - in my home directory I've added .asoundrc file in which I force rate of my default sound device. Maybe this is the difference? – Jacek Sep 08 '20 at 11:00

0 Answers0