Home | History | Annotate | Download | only in pcm
      1 /**
      2  * \file pcm/pcm_asym.c
      3  * \ingroup PCM_Plugins
      4  * \brief PCM Asymmetrical Plugin Interface
      5  * \author Takashi Iwai <tiwai (at) suse.de>
      6  * \date 2003
      7  */
      8 
      9 #include "pcm_local.h"
     10 
     11 #ifndef PIC
     12 /* entry for static linking */
     13 const char *_snd_module_pcm_asym = "";
     14 #endif
     15 
     16 /*! \page pcm_plugins
     17 
     18 \section pcm_plugins_asym Plugin: asym
     19 
     20 This plugin is a combination of playback and capture PCM streams.
     21 Slave PCMs can be defined asymmetrically for both directions.
     22 
     23 \code
     24 pcm.name {
     25         type asym               # Asym PCM
     26         playback STR            # Playback slave name
     27         # or
     28         playback {              # Playback slave definition
     29                 pcm STR         # Slave PCM name
     30                 # or
     31                 pcm { }         # Slave PCM definition
     32         }
     33         capture STR             # Capture slave name
     34         # or
     35         capture {               # Capture slave definition
     36                 pcm STR         # Slave PCM name
     37                 # or
     38                 pcm { }         # Slave PCM definition
     39         }
     40 }
     41 \endcode
     42 
     43 For example, you can combine a dmix plugin and a dsnoop plugin as
     44 as a single PCM for playback and capture directions, respectively.
     45 \code
     46 pcm.duplex {
     47 	type asym
     48 	playback.pcm "dmix"
     49 	capture.pcm "dsnoop"
     50 }
     51 \endcode
     52 
     53 By defining only a single direction, the resultant PCM becomes
     54 half-duplex.
     55 
     56 \subsection pcm_plugins_asym_funcref Function reference
     57 
     58 <UL>
     59   <LI>_snd_pcm_asym_open()
     60 </UL>
     61 
     62 */
     63 
     64 /**
     65  * \brief Creates a new asym stream PCM
     66  * \param pcmp Returns created PCM handle
     67  * \param name Name of PCM
     68  * \param root Root configuration node
     69  * \param conf Configuration node with copy PCM description
     70  * \param stream Stream type
     71  * \param mode Stream mode
     72  * \retval zero on success otherwise a negative error code
     73  * \warning Using of this function might be dangerous in the sense
     74  *          of compatibility reasons. The prototype might be freely
     75  *          changed in future.
     76  */
     77 int _snd_pcm_asym_open(snd_pcm_t **pcmp, const char *name ATTRIBUTE_UNUSED,
     78 			 snd_config_t *root, snd_config_t *conf,
     79 			 snd_pcm_stream_t stream, int mode)
     80 {
     81 	snd_config_iterator_t i, next;
     82 	int err;
     83 	snd_config_t *slave = NULL, *sconf;
     84 	snd_config_for_each(i, next, conf) {
     85 		snd_config_t *n = snd_config_iterator_entry(i);
     86 		const char *id;
     87 		if (snd_config_get_id(n, &id) < 0)
     88 			continue;
     89 		if (snd_pcm_conf_generic_id(id))
     90 			continue;
     91 		if (strcmp(id, "playback") == 0) {
     92 			if (stream == SND_PCM_STREAM_PLAYBACK)
     93 				slave = n;
     94 			continue;
     95 		}
     96 		if (strcmp(id, "capture") == 0) {
     97 			if (stream == SND_PCM_STREAM_CAPTURE)
     98 				slave = n;
     99 			continue;
    100 		}
    101 		SNDERR("Unknown field %s", id);
    102 		return -EINVAL;
    103 	}
    104 	if (! slave) {
    105 		SNDERR("%s slave is not defined",
    106 		       stream == SND_PCM_STREAM_PLAYBACK ? "playback" : "capture");
    107 		return -EINVAL;
    108 	}
    109 	err = snd_pcm_slave_conf(root, slave, &sconf, 0);
    110 	if (err < 0)
    111 		return err;
    112 	err = snd_pcm_open_named_slave(pcmp, name, root, sconf, stream,
    113 				       mode, conf);
    114 	snd_config_delete(sconf);
    115 	return err;
    116 }
    117 #ifndef DOC_HIDDEN
    118 SND_DLSYM_BUILD_VERSION(_snd_pcm_asym_open, SND_PCM_DLSYM_VERSION);
    119 #endif
    120