In one of our projects we have a sound generator attached to a Raspberry Pi, and the mission is to control the sound volume in real time, (think turning a knob).
The alternative is to use the ALSA API to write a native Linux C library that we can easily integrate into our existing code. Furthermore this approach has the added benefit that it can easily be interoped from managed languages.
The code is simplified to work on devices that only have one hardware audio interface, but if needed it can support multiple interfaces with a few tweaks.
Enough talking, here’s an example on how to set the volume:
snd_mixer_t *handle; // ALSA mixer sound card handle snd_mixer_elem_t *elem; // ALSA mixer snd_mixer_selem_id_t *mixer_id; // ALSA mixer simple element // Open an empty mixer snd_mixer_open(handle, SND_MIXER_ELEM_SIMPLE); // Open the default interface, see: $ cat /proc/asound/cards // alternatively, this can be "hw:0" instead of "default" snd_mixer_attach(*handle, "default"); snd_mixer_selem_register(*handle, NULL, NULL); // Load the mixer elements snd_mixer_load(*handle); snd_mixer_selem_id_alloca(mixer_id); snd_mixer_selem_id_set_index(*mixer_id, 0); // PCM is the default interface, see: $ amixer snd_mixer_selem_id_set_name(*mixer_id, "PCM"); *elem = snd_mixer_find_selem(*handle, *mixer_id); // sets the volume for all the channels to the assigned dV value snd_mixer_selem_set_playback_dB_all(elem, dB_value, 0); // detach a previously attached HCTL to an opened mixer freeing all related resources. snd_mixer_detach(*handle, "default"); // close a mixer and free all related resources. snd_mixer_close(*handle);
Source code: https://github.com/radutomy/libsoundctrl