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