Impostare il volume dei singoli due canali del mixer di ALSA
Utilizzando alcune risorse dell'interfaccia Mixer di ALSA, è possibile - fra l'altro - impostare e modificare il volume audio di ciascuno dei due canali del mixer.
Sarà ovviamente necessario richiamare in Gambas la libreria condivisa di ALSA: "libasound.so.2.0.0 ".
Mostriamo di seguito due semplici esempi, uno riferito ad un'applicazione a riga di comando e l'altro riferito ad un'applicazione grafica.
Esempio con un'applicazione a riga di comando
In questo esempio bisognerà scrivere nell'apposito spazio al di sotto della console (oppure nel Terminale) del progetto Gambas un valore compreso tra 0 e 100 per impostare il volume audio di ciascun canale del mixer di ALSA per volta.
Library "libasound:2.0.0" Private Enum SND_MIXER_SCHN_MONO = 0, SND_MIXER_SCHN_FRONT_LEFT = 0, SND_MIXER_SCHN_FRONT_RIGHT ' int snd_mixer_open (snd_mixer_t **mixer, int mode) ' Opens an empty mixer. Private Extern snd_mixer_open(mixer As Pointer, mode As Integer) As Integer ' int snd_mixer_attach (snd_mixer_t *mixer, const char *name) ' Attach an HCTL specified with the CTL device name to an opened mixer. Private Extern snd_mixer_attach(mixer As Pointer, name As String) As Integer ' int snd_mixer_selem_register (snd_mixer_t *mixer, struct snd_mixer_selem_regopt *options, snd_mixer_class_t **classp) ' Register mixer simple element class. Private Extern snd_mixer_selem_register(mixer As Pointer, options As Pointer, classp As Pointer) As Integer ' int snd_mixer_load (snd_mixer_t *mixer) ' Load a mixer elements. Private Extern snd_mixer_load(mixer As Pointer) As Integer ' int snd_mixer_selem_id_malloc (snd_mixer_selem_id_t **ptr) ' Allocate an invalid snd_mixer_selem_id_t using standard malloc. Private Extern snd_mixer_selem_id_malloc(ptr As Pointer) As Integer ' void snd_mixer_selem_id_set_index (snd_mixer_selem_id_t *obj, unsigned int val) ' Set index part of a mixer simple element identifier. Private Extern snd_mixer_selem_id_set_index(obj As Pointer, ival As Integer) ' void snd_mixer_selem_id_set_name (snd_mixer_selem_id_t *obj, const char *val) ' Set name part of a mixer simple element identifier. Private Extern snd_mixer_selem_id_set_name(obj As Pointer, sval As String) ' snd_mixer_elem_t * snd_mixer_find_selem (snd_mixer_t *mixer, const snd_mixer_selem_id_t *id) ' Find a mixer simple element. Private Extern snd_mixer_find_selem(mixer As Pointer, id As Pointer) As Pointer ' int snd_mixer_selem_get_playback_volume_range (snd_mixer_elem_t *elem, long *min, long *max) ' Get range for playback volume of a mixer simple element. Private Extern snd_mixer_selem_get_playback_volume_range(elem As Pointer, lmin As Long, lmax As Long) As Integer ' int snd_mixer_selem_set_playback_volume (snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value) ' Set value of playback volume control of a mixer simple element. Private Extern snd_mixer_selem_set_playback_volume(elem As Pointer, channel As Integer, value As Integer) As Integer ' int snd_mixer_close (snd_mixer_t *mixer) ' Close a mixer and free all related resources. Private Extern snd_mixer_close(mixer As Pointer) As Integer Public Sub Main() Dim handle, sid, el As Pointer Dim err, i As Integer Dim can, vol As String Dim volume, mini, maxi As Long err = snd_mixer_open(VarPtr(handle), 0) If err < 0 Then Error.Raise("Impossibile inizializzare il sub-sistema 'Mixer' di ALSA !") snd_mixer_attach(handle, "default") snd_mixer_selem_register(handle, 0, 0) snd_mixer_load(handle) snd_mixer_selem_id_malloc(VarPtr(sid)) snd_mixer_selem_id_set_index(sid, 0) snd_mixer_selem_id_set_name(sid, "Master") el = snd_mixer_find_selem(handle, sid) can = "sinistro." snd_mixer_selem_get_playback_volume_range(el, VarPtr(mini), VarPtr(maxi)) For i = 0 to SND_MIXER_SCHN_FRONT_RIGHT if i = SND_MIXER_SCHN_FRONT_RIGHT Then can = "destro." Print "Immettere un valore (0 - 100) per impostare il volume del canale "; can Input vol volume = CLong(Val(vol)) snd_mixer_selem_set_playback_volume(el, i, volume * maxi / 100) Next ' Va in chiusura: snd_mixer_close(handle) End
Esempio con un'applicazione in ambiente grafico
In questo esempio in ambiente grafico la modifica del volume (tra 0 e 100) dei due canali avverrà mediante due distinti Slider, mentre la visualizzazione del valore del volume di ciascun canale avverrà mediante due ValueBox.
Private handle As Pointer Private el As Pointer Private maxi As Long Library "libasound:2.0.0" Private Enum SND_MIXER_SCHN_MONO = 0, SND_MIXER_SCHN_FRONT_LEFT = 0, SND_MIXER_SCHN_FRONT_RIGHT ' int snd_mixer_open (snd_mixer_t **mixer, int mode) ' Opens an empty mixer. Private Extern snd_mixer_open(mixer As Pointer, mode As Integer) As Integer ' int snd_mixer_attach (snd_mixer_t *mixer, const char *name) ' Attach an HCTL specified with the CTL device name to an opened mixer. Private Extern snd_mixer_attach(mixer As Pointer, name As String) As Integer ' int snd_mixer_selem_register (snd_mixer_t *mixer, struct snd_mixer_selem_regopt *options, snd_mixer_class_t **classp) ' Register mixer simple element class. Private Extern snd_mixer_selem_register(mixer As Pointer, options As Pointer, classp As Pointer) As Integer ' int snd_mixer_load (snd_mixer_t *mixer) ' Load a mixer elements. Private Extern snd_mixer_load(mixer As Pointer) As Integer ' int snd_mixer_selem_id_malloc (snd_mixer_selem_id_t **ptr) ' Allocate an invalid snd_mixer_selem_id_t using standard malloc. Private Extern snd_mixer_selem_id_malloc(ptr As Pointer) As Integer ' void snd_mixer_selem_id_set_index (snd_mixer_selem_id_t *obj, unsigned int val) ' Set index part of a mixer simple element identifier. Private Extern snd_mixer_selem_id_set_index(obj As Pointer, ival As Integer) ' void snd_mixer_selem_id_set_name (snd_mixer_selem_id_t *obj, const char *val) ' Set name part of a mixer simple element identifier. Private Extern snd_mixer_selem_id_set_name(obj As Pointer, sval As String) ' snd_mixer_elem_t * snd_mixer_find_selem (snd_mixer_t *mixer, const snd_mixer_selem_id_t *id) ' Find a mixer simple element. Private Extern snd_mixer_find_selem(mixer As Pointer, id As Pointer) As Pointer ' int snd_mixer_selem_get_playback_volume (snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value) ' Return value of playback volume control of a mixer simple element. Private Extern snd_mixer_selem_get_playback_volume(elem As Pointer, channel As Integer, value As Pointer) As Integer ' int snd_mixer_selem_get_playback_volume_range (snd_mixer_elem_t *elem, long *min, long *max) ' Get range for playback volume of a mixer simple element. Private Extern snd_mixer_selem_get_playback_volume_range(elem As Pointer, lmin As Long, lmax As Long) As Integer ' int snd_mixer_selem_set_playback_volume (snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value) ' Set value of playback volume control of a mixer simple element. Private Extern snd_mixer_selem_set_playback_volume(elem As Pointer, channel As Integer, value As Integer) As Integer ' int snd_mixer_close (snd_mixer_t *mixer) ' Close a mixer and free all related resources. Private Extern snd_mixer_close(mixer As Pointer) As Integer Public Sub Form_Open() Dim sid As Pointer Dim err As Integer Dim vld, vls, mini As Long err = snd_mixer_open(VarPtr(handle), 0) If err < 0 Then Error.Raise("Impossibile inizializzare il sub-sistema 'Mixer' di ALSA !") snd_mixer_attach(handle, "default") snd_mixer_selem_register(handle, 0, 0) snd_mixer_load(handle) snd_mixer_selem_id_malloc(VarPtr(sid)) snd_mixer_selem_id_set_index(sid, 0) snd_mixer_selem_id_set_name(sid, "Master") el = snd_mixer_find_selem(handle, sid) ' Ottiene l'attuale volume di ciascuno dei due canali del Mixer di ALSA: snd_mixer_selem_get_playback_volume(el, SND_MIXER_SCHN_FRONT_RIGHT, VarPtr(vld)) snd_mixer_selem_get_playback_volume(el, SND_MIXER_SCHN_FRONT_LEFT, VarPtr(vls)) snd_mixer_selem_get_playback_volume_range(el, VarPtr(mini), VarPtr(maxi)) With Slider1 .MinValue = 0 .MaxValue = 100 .Value = Round((vls * 100) / maxi) End With With Slider2 .MinValue = 0 .MaxValue = 100 .Value = Round((vld * 100) / maxi) End With End Public Sub Slider1_Change() Dim volume As Long volume = CLong(Slider1.Value) snd_mixer_selem_set_playback_volume(el, SND_MIXER_SCHN_FRONT_LEFT, volume * maxi / 100) ValueBox1.Value = volume End Public Sub Slider2_Change() Dim volume As Long volume = CLong(Slider2.Value) snd_mixer_selem_set_playback_volume(el, SND_MIXER_SCHN_FRONT_RIGHT, volume * maxi / 100) ValueBox2.Value = volume End Public Sub Form_Close() snd_mixer_close(handle) End