2

I want to implement (mute/unmute and volume up/down) for Speaker and Headphone using c program.Using amixer command line utility as shown in this link https://askubuntu.com/questions/371970/how-to-switch-between-headphones-and-speakers-manually-from-command-line it works ,same things I need to implement using C program.

So I tried following different ways. I seen this example for volume control of Master Set ALSA master volume from C code

and for mute/unmute of Master Linux ALSA/Sound-API Questions - How do you mute?

both solution works perfect for Master configuration. But here in my case I want to implement same functionality for speaker and headphone.So instead of "Master" if I replaced selem_name with Speaker or Headphone+L0 which I found using amixer command it throws error.

Here I need to mute/unmute "Speaker" or "Headphone".

If I use *selem_name = "Speaker" or "Headphone" in below code it throws error shown below:

Is given selem_name is invalid? If so how can I List out valid selem_name for speaker and Headphone? The one I used its figured out from amixer command line utility.

What API I have to use for Speaker and Headphone?

Errorr eturn by test.c program:

alsa: simple.c:346: snd_mixer_selem_has_playback_switch: Assertion 
`elem' failed.
Aborted

//test.c

#include<stdio.h>
#include<alsa/asoundlib.h>

void SetAlsaSpeakerMute()
{
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;
    const char *card = "default";

    const char *selem_name = "Speaker";

    snd_mixer_open(&handle, 0);
    snd_mixer_attach(handle, card);
    snd_mixer_selem_register(handle, NULL, NULL);
    snd_mixer_load(handle);

    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem_name);
    snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);

    if (snd_mixer_selem_has_playback_switch(elem)) {
        snd_mixer_selem_set_playback_switch_all(elem, 0);
    }

    snd_mixer_close(handle);
}

int main()
{
    SetAlsaSpeakerMute();
    return 0;
}
//For const char *selem_name = "Master" this program works fine.
//This can mute Mixer of default sound card

void SetAlsaMasterMute()
{
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;
    const char *card = "default";
    const char *selem_name = "Master";

    snd_mixer_open(&handle, 0);
    snd_mixer_attach(handle, card);
    snd_mixer_selem_register(handle, NULL, NULL);
    snd_mixer_load(handle);

    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem_name);
    snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);

    if (snd_mixer_selem_has_playback_switch(elem)) {
        snd_mixer_selem_set_playback_switch_all(elem, 0);
    }

    snd_mixer_close(handle);
}

Is there any solution to mute/unmute specific device(speaker and headphone)?All help appreciate thanks.

raj123
  • 564
  • 2
  • 10
  • 27
  • Which line is *`simple.c:346`*? – jww Apr 25 '19 at 02:52
  • Its a returning error message . It shows alsa library function snd_mixer_selem_has_playback_switch() located in alsa librray file simple.c gives error. – raj123 Apr 25 '19 at 03:38
  • This code lacks error handling. For any function that returns an error code, yout must check it. – CL. Apr 25 '19 at 06:37
  • yes it is.But its a just sample code.It not solve my problem about mute/unmute headphone and speaker @CL – raj123 Apr 25 '19 at 06:39
  • 1
    I don't think this question deserves closure - it's about programming (of libalsa). – mvp Apr 26 '19 at 21:03
  • List all controls using 'amixer scontrols' and use only valid names. Apparently, elem is NULL for your hardware. – perexg Apr 27 '19 at 05:37
  • Currently I am using name given by `amixer -c 0` command and same name works for command `amixer set "Speaker" mute` this command mute Speaker @perexg – raj123 Apr 28 '19 at 04:51

1 Answers1

1

Again, elem variable seems to be NULL for the control name you're using.

You should check the control ID (name, index, interface) and the control device for the mixer connection. The 'default' device name usually redirects to pulse audio (only Master / PCM controls). If you use '-c 0' for amixer, the correct device name is 'hw:0' (const char *card = "hw:0";).

perexg
  • 26
  • 1