[alsa-devel] Softvol controls
John Utz
john.utz at dmx.com
Fri Nov 30 00:46:57 CET 2007
Hi Lennart!
On Fri, 30 Nov 2007 00:28:59 +0100
"Lennart Poettering" <mznyfn at 0pointer.de> wrote:
> On Wed, 21.11.07 12:22, Takashi Iwai (tiwai at suse.de) wrote:
>
> > > Now, is there a way I can detect for a mixer element if it is
> > > "real" or if it is implemented only for the "plughw" PCM? As it
> > > seems the "hw:0" mixer device does contain "virtual" tracks,
> > > isn't that a bit strange? Shouldn't the virtual mixer tracks be
> > > available only in a mixer device "plughw:0"? That at least would
> > > be symmetric to the PCM case, wouldn't it?
> >
> > Check snd_ctl_elem_info_is_user(). All softvol controls are
> > implemented as user elements.
>
> Hmm, how am I supposed to get the snd_ctl_elem_info_t from a
> snd_mixer_elem_t or snd_mixer_selem_id_t?
>
> I figure there is no useful documentation or even example how this is
> supposed to work? Hmm, is there any real documentation available which
> describes the relation of ctl, hctl, mixer and smixer at all? For the
> uninitated the whols structure looks overly complex and redundant.
Here's my take on it....HTH
dont hesitate to ask
// ALSA Mixer creation and manipulation routines
//
// The alsa api is pretty cool once you find a working example :-)
//
// One first creates the mixer representation and then 1 element
// representation for each item that you need to manipulate.
// create the individual elements, ie PCM, Surround, etc
snd_mixer_elem_t *
alsa_mixer_elem_instantiate(char *pNameElem, snd_mixer_t *pSndMxr)
{
char acLog[256] = "";
int iErr = 0;
snd_mixer_elem_t *pSndMxrElem;
snd_mixer_selem_id_t *pSndMxrSlem;
snd_mixer_selem_id_alloca(&pSndMxrSlem);
snd_mixer_selem_id_set_name(pSndMxrSlem, pNameElem);
sprintf(acLog, "Initializing ALSA Mixer Element: %s", pNameElem);
aeiu_logprint("PC18", AEIU_LOG_INFO, acLog);
// find element based on name
if(!(pSndMxrElem=snd_mixer_find_selem(pSndMxr, pSndMxrSlem))) goto
fin;
// make sure they are turned on so we can hear them, not always the
case
aeiu_logprint("PC19", AEIU_LOG_INFO, "ALSA Mixer Element Enable" );
if(snd_mixer_selem_has_playback_switch(pSndMxrElem))
if((iErr=snd_mixer_selem_set_playback_switch_all(pSndMxrElem, 1)))
goto fin;
// configure them for the old style 0-100 oss volume range
aeiu_logprint("PC20", AEIU_LOG_INFO, "ALSA Mixer Element Set
Range" );
if((iErr=snd_mixer_selem_set_playback_volume_range(pSndMxrElem, 0,
100))) goto fin;
// set to a reasonable starting value
aeiu_logprint("PC21", AEIU_LOG_INFO, "ALSA Mixer Element Set
Volume" );
if((iErr=snd_mixer_selem_set_playback_volume_all(pSndMxrElem, 65)))
goto fin;
fin:
if(!pSndMxrElem || iErr)
{
sprintf(acLog,"alsa_mixer_elem_instantiate: %s Failed: %s\n",
pNameElem, iErr ? snd_strerror(iErr) : "Mixer Device Not Found");
aeiu_logprint("PC22", AEIU_LOG_ERROR, acLog);
}
return pSndMxrElem;
}
int
alsa_mixer_instantiate()
{
int iErr = 0;
char *pcNameDevMxr = "default";
aeiu_logprint("PC23", AEIU_LOG_INFO, "Initializing ALSA Mixer");
if(gpSndMxr)
{
aeiu_logprint("PC24", AEIU_LOG_ERROR,"alsa_mixer_instantiate:
pSndMxr!=NULL"); iErr=1;
goto fin;
}
if((iErr = snd_mixer_open(&gpSndMxr, 0))) goto fin;
if((iErr = snd_mixer_attach(gpSndMxr, pcNameDevMxr))) goto fin;
if((iErr = snd_mixer_selem_register(gpSndMxr, NULL, NULL))) goto fin;
if((iErr = snd_mixer_load(gpSndMxr))) goto fin;
// mixer device is now live, create the control elements, note that
// we dont error check here because we do it in the function and we
// dont want to break execution flow here if we fail for some reason
// (rather have 2 channels than no channels!)
gpSndMxrElemCrdV = alsa_mixer_elem_instantiate("PCM", gpSndMxr);
gpSndMxrElemCrd0 = alsa_mixer_elem_instantiate("Master", gpSndMxr);
gpSndMxrElemCrd1 = alsa_mixer_elem_instantiate("Surround", gpSndMxr);
// this exists only for a function called pcm_lowervolumes()
gpSndMxrElemCrdM = alsa_mixer_elem_instantiate("Mic", gpSndMxr);
fin:
if(iErr)
{
if(gpSndMxr)
{
snd_mixer_close(gpSndMxr);
gpSndMxr = NULL;
}
char acLog[256] = "";
sprintf(acLog, "alsa_mixer_instantiate: Failed: %s",
snd_strerror(iErr)); aeiu_logprint("PC25", AEIU_LOG_ERROR, acLog);
}
return iErr;
}
> Lennart
>
More information about the Alsa-devel
mailing list