Blame src/pcm/pcm_asym.c

Packit 4a16fb
/**
Packit 4a16fb
 * \file pcm/pcm_asym.c
Packit 4a16fb
 * \ingroup PCM_Plugins
Packit 4a16fb
 * \brief PCM Asymmetrical Plugin Interface
Packit 4a16fb
 * \author Takashi Iwai <tiwai@suse.de>
Packit 4a16fb
 * \date 2003
Packit 4a16fb
 */
Packit 4a16fb
Packit 4a16fb
#include "pcm_local.h"
Packit 4a16fb
Packit 4a16fb
#ifndef PIC
Packit 4a16fb
/* entry for static linking */
Packit 4a16fb
const char *_snd_module_pcm_asym = "";
Packit 4a16fb
#endif
Packit 4a16fb
Packit 4a16fb
/*! \page pcm_plugins
Packit 4a16fb
Packit 4a16fb
\section pcm_plugins_asym Plugin: asym
Packit 4a16fb
Packit 4a16fb
This plugin is a combination of playback and capture PCM streams.
Packit 4a16fb
Slave PCMs can be defined asymmetrically for both directions.
Packit 4a16fb
Packit 4a16fb
\code
Packit 4a16fb
pcm.name {
Packit 4a16fb
        type asym               # Asym PCM
Packit 4a16fb
        playback STR            # Playback slave name
Packit 4a16fb
        # or
Packit 4a16fb
        playback {              # Playback slave definition
Packit 4a16fb
                pcm STR         # Slave PCM name
Packit 4a16fb
                # or
Packit 4a16fb
                pcm { }         # Slave PCM definition
Packit 4a16fb
        }
Packit 4a16fb
        capture STR             # Capture slave name
Packit 4a16fb
        # or
Packit 4a16fb
        capture {               # Capture slave definition
Packit 4a16fb
                pcm STR         # Slave PCM name
Packit 4a16fb
                # or
Packit 4a16fb
                pcm { }         # Slave PCM definition
Packit 4a16fb
        }
Packit 4a16fb
}
Packit 4a16fb
\endcode
Packit 4a16fb
Packit 4a16fb
For example, you can combine a dmix plugin and a dsnoop plugin as
Packit 4a16fb
as a single PCM for playback and capture directions, respectively.
Packit 4a16fb
\code
Packit 4a16fb
pcm.duplex {
Packit 4a16fb
	type asym
Packit 4a16fb
	playback.pcm "dmix"
Packit 4a16fb
	capture.pcm "dsnoop"
Packit 4a16fb
}
Packit 4a16fb
\endcode
Packit 4a16fb
Packit 4a16fb
By defining only a single direction, the resultant PCM becomes
Packit 4a16fb
half-duplex.
Packit 4a16fb
Packit 4a16fb
\subsection pcm_plugins_asym_funcref Function reference
Packit 4a16fb
Packit 4a16fb
    Packit 4a16fb
      
  • _snd_pcm_asym_open()
  • Packit 4a16fb
    Packit 4a16fb
    Packit 4a16fb
    */
    Packit 4a16fb
    Packit 4a16fb
    /**
    Packit 4a16fb
     * \brief Creates a new asym stream PCM
    Packit 4a16fb
     * \param pcmp Returns created PCM handle
    Packit 4a16fb
     * \param name Name of PCM
    Packit 4a16fb
     * \param root Root configuration node
    Packit 4a16fb
     * \param conf Configuration node with copy PCM description
    Packit 4a16fb
     * \param stream Stream type
    Packit 4a16fb
     * \param mode Stream mode
    Packit 4a16fb
     * \retval zero on success otherwise a negative error code
    Packit 4a16fb
     * \warning Using of this function might be dangerous in the sense
    Packit 4a16fb
     *          of compatibility reasons. The prototype might be freely
    Packit 4a16fb
     *          changed in future.
    Packit 4a16fb
     */
    Packit 4a16fb
    int _snd_pcm_asym_open(snd_pcm_t **pcmp, const char *name ATTRIBUTE_UNUSED,
    Packit 4a16fb
    			 snd_config_t *root, snd_config_t *conf,
    Packit 4a16fb
    			 snd_pcm_stream_t stream, int mode)
    Packit 4a16fb
    {
    Packit 4a16fb
    	snd_config_iterator_t i, next;
    Packit 4a16fb
    	int err;
    Packit 4a16fb
    	snd_config_t *slave = NULL, *sconf;
    Packit 4a16fb
    	snd_config_for_each(i, next, conf) {
    Packit 4a16fb
    		snd_config_t *n = snd_config_iterator_entry(i);
    Packit 4a16fb
    		const char *id;
    Packit 4a16fb
    		if (snd_config_get_id(n, &id) < 0)
    Packit 4a16fb
    			continue;
    Packit 4a16fb
    		if (snd_pcm_conf_generic_id(id))
    Packit 4a16fb
    			continue;
    Packit 4a16fb
    		if (strcmp(id, "playback") == 0) {
    Packit 4a16fb
    			if (stream == SND_PCM_STREAM_PLAYBACK)
    Packit 4a16fb
    				slave = n;
    Packit 4a16fb
    			continue;
    Packit 4a16fb
    		}
    Packit 4a16fb
    		if (strcmp(id, "capture") == 0) {
    Packit 4a16fb
    			if (stream == SND_PCM_STREAM_CAPTURE)
    Packit 4a16fb
    				slave = n;
    Packit 4a16fb
    			continue;
    Packit 4a16fb
    		}
    Packit 4a16fb
    		SNDERR("Unknown field %s", id);
    Packit 4a16fb
    		return -EINVAL;
    Packit 4a16fb
    	}
    Packit 4a16fb
    	if (! slave) {
    Packit 4a16fb
    		SNDERR("%s slave is not defined",
    Packit 4a16fb
    		       stream == SND_PCM_STREAM_PLAYBACK ? "playback" : "capture");
    Packit 4a16fb
    		return -EINVAL;
    Packit 4a16fb
    	}
    Packit 4a16fb
    	err = snd_pcm_slave_conf(root, slave, &sconf, 0);
    Packit 4a16fb
    	if (err < 0)
    Packit 4a16fb
    		return err;
    Packit 4a16fb
    	err = snd_pcm_open_named_slave(pcmp, name, root, sconf, stream,
    Packit 4a16fb
    				       mode, conf);
    Packit 4a16fb
    	snd_config_delete(sconf);
    Packit 4a16fb
    	return err;
    Packit 4a16fb
    }
    Packit 4a16fb
    #ifndef DOC_HIDDEN
    Packit 4a16fb
    SND_DLSYM_BUILD_VERSION(_snd_pcm_asym_open, SND_PCM_DLSYM_VERSION);
    Packit 4a16fb
    #endif