Blame src/pcm/pcm_null.c

Packit Service db8eaa
/**
Packit Service db8eaa
 * \file pcm/pcm_null.c
Packit Service db8eaa
 * \ingroup PCM_Plugins
Packit Service db8eaa
 * \brief PCM Null Plugin Interface
Packit Service db8eaa
 * \author Abramo Bagnara <abramo@alsa-project.org>
Packit Service db8eaa
 * \date 2000-2001
Packit Service db8eaa
 */
Packit Service db8eaa
/*
Packit Service db8eaa
 *  PCM - Null plugin
Packit Service db8eaa
 *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
Packit Service db8eaa
 *
Packit Service db8eaa
 *
Packit Service db8eaa
 *   This library is free software; you can redistribute it and/or modify
Packit Service db8eaa
 *   it under the terms of the GNU Lesser General Public License as
Packit Service db8eaa
 *   published by the Free Software Foundation; either version 2.1 of
Packit Service db8eaa
 *   the License, or (at your option) any later version.
Packit Service db8eaa
 *
Packit Service db8eaa
 *   This program is distributed in the hope that it will be useful,
Packit Service db8eaa
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service db8eaa
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service db8eaa
 *   GNU Lesser General Public License for more details.
Packit Service db8eaa
 *
Packit Service db8eaa
 *   You should have received a copy of the GNU Lesser General Public
Packit Service db8eaa
 *   License along with this library; if not, write to the Free Software
Packit Service db8eaa
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit Service db8eaa
 *
Packit Service db8eaa
 */
Packit Service db8eaa
  
Packit Service db8eaa
#include "bswap.h"
Packit Service db8eaa
#include <limits.h>
Packit Service db8eaa
#include "pcm_local.h"
Packit Service db8eaa
#include "pcm_plugin.h"
Packit Service db8eaa
Packit Service db8eaa
#ifndef PIC
Packit Service db8eaa
/* entry for static linking */
Packit Service db8eaa
const char *_snd_module_pcm_null = "";
Packit Service db8eaa
#endif
Packit Service db8eaa
Packit Service db8eaa
#ifndef DOC_HIDDEN
Packit Service db8eaa
typedef struct {
Packit Service db8eaa
	snd_htimestamp_t trigger_tstamp;
Packit Service db8eaa
	snd_pcm_state_t state;
Packit Service db8eaa
	snd_pcm_uframes_t appl_ptr;
Packit Service db8eaa
	snd_pcm_uframes_t hw_ptr;
Packit Service db8eaa
	int poll_fd;
Packit Service db8eaa
	snd_pcm_chmap_query_t **chmap;
Packit Service db8eaa
} snd_pcm_null_t;
Packit Service db8eaa
#endif
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_close(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
	close(null->poll_fd);
Packit Service db8eaa
	free(null);
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED)
Packit Service db8eaa
{
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_async(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int sig ATTRIBUTE_UNUSED, pid_t pid ATTRIBUTE_UNUSED)
Packit Service db8eaa
{
Packit Service db8eaa
	return -ENOSYS;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
Packit Service db8eaa
{
Packit Service db8eaa
	memset(info, 0, sizeof(*info));
Packit Service db8eaa
	info->stream = pcm->stream;
Packit Service db8eaa
	info->card = -1;
Packit Service db8eaa
	if (pcm->name) {
Packit Service db8eaa
		snd_strlcpy((char *)info->id, pcm->name, sizeof(info->id));
Packit Service db8eaa
		snd_strlcpy((char *)info->name, pcm->name, sizeof(info->name));
Packit Service db8eaa
		snd_strlcpy((char *)info->subname, pcm->name, sizeof(info->subname));
Packit Service db8eaa
	}
Packit Service db8eaa
	info->subdevices_count = 1;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_avail_update(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
        if (null->state == SND_PCM_STATE_PREPARED) {
Packit Service db8eaa
                /* it is required to return the correct avail count for */
Packit Service db8eaa
                /* the prepared stream, otherwise the start is not called */
Packit Service db8eaa
                return snd_pcm_mmap_avail(pcm);
Packit Service db8eaa
        }
Packit Service db8eaa
	return pcm->buffer_size;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
	memset(status, 0, sizeof(*status));
Packit Service db8eaa
	status->state = null->state;
Packit Service db8eaa
	status->trigger_tstamp = null->trigger_tstamp;
Packit Service 01c0b7
	status->appl_ptr = *pcm->appl.ptr;
Packit Service 01c0b7
	status->hw_ptr = *pcm->hw.ptr;
Packit Service db8eaa
	gettimestamp(&status->tstamp, pcm->tstamp_type);
Packit Service db8eaa
	status->avail = snd_pcm_null_avail_update(pcm);
Packit Service db8eaa
	status->avail_max = pcm->buffer_size;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_state_t snd_pcm_null_state(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
	return null->state;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_hwsync(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
Packit Service db8eaa
{
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_delay(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sframes_t *delayp)
Packit Service db8eaa
{
Packit Service db8eaa
	*delayp = 0;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_reset(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	*pcm->appl.ptr = 0;
Packit Service db8eaa
	*pcm->hw.ptr = 0;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_prepare(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
	null->state = SND_PCM_STATE_PREPARED;
Packit Service db8eaa
	return snd_pcm_null_reset(pcm);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_start(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
	assert(null->state == SND_PCM_STATE_PREPARED);
Packit Service db8eaa
	null->state = SND_PCM_STATE_RUNNING;
Packit Service db8eaa
	if (pcm->stream == SND_PCM_STREAM_CAPTURE)
Packit Service db8eaa
		*pcm->hw.ptr = *pcm->appl.ptr + pcm->buffer_size;
Packit Service db8eaa
	else
Packit Service db8eaa
		*pcm->hw.ptr = *pcm->appl.ptr;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_drop(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
	assert(null->state != SND_PCM_STATE_OPEN);
Packit Service db8eaa
	null->state = SND_PCM_STATE_SETUP;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_drain(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
	assert(null->state != SND_PCM_STATE_OPEN);
Packit Service db8eaa
	null->state = SND_PCM_STATE_SETUP;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_pause(snd_pcm_t *pcm, int enable)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
	if (enable) {
Packit Service db8eaa
		if (null->state != SND_PCM_STATE_RUNNING)
Packit Service db8eaa
			return -EBADFD;
Packit Service db8eaa
		null->state = SND_PCM_STATE_PAUSED;
Packit Service db8eaa
	} else {
Packit Service db8eaa
		if (null->state != SND_PCM_STATE_PAUSED)
Packit Service db8eaa
			return -EBADFD;
Packit Service db8eaa
		null->state = SND_PCM_STATE_RUNNING;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_rewindable(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	return pcm->buffer_size;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_forwardable(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
Packit Service db8eaa
{
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
	switch (null->state) {
Packit Service db8eaa
	case SND_PCM_STATE_RUNNING:
Packit Service db8eaa
		snd_pcm_mmap_hw_backward(pcm, frames);
Packit Service db8eaa
		/* Fall through */
Packit Service db8eaa
	case SND_PCM_STATE_PREPARED:
Packit Service db8eaa
		snd_pcm_mmap_appl_backward(pcm, frames);
Packit Service db8eaa
		return frames;
Packit Service db8eaa
	default:
Packit Service db8eaa
		return -EBADFD;
Packit Service db8eaa
	}
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
	switch (null->state) {
Packit Service db8eaa
	case SND_PCM_STATE_RUNNING:
Packit Service db8eaa
		snd_pcm_mmap_hw_forward(pcm, frames);
Packit Service db8eaa
		/* Fall through */
Packit Service db8eaa
	case SND_PCM_STATE_PREPARED:
Packit Service db8eaa
		snd_pcm_mmap_appl_forward(pcm, frames);
Packit Service db8eaa
		return frames;
Packit Service db8eaa
	default:
Packit Service db8eaa
		return -EBADFD;
Packit Service db8eaa
	}
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_resume(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
Packit Service db8eaa
{
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_xfer_areas(snd_pcm_t *pcm,
Packit Service db8eaa
						 const snd_pcm_channel_area_t *areas ATTRIBUTE_UNUSED,
Packit Service db8eaa
						 snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
Packit Service db8eaa
						 snd_pcm_uframes_t size)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_mmap_appl_forward(pcm, size);
Packit Service db8eaa
	snd_pcm_mmap_hw_forward(pcm, size);
Packit Service db8eaa
	return size;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_writei(snd_pcm_t *pcm, const void *buffer ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
Packit Service db8eaa
{
Packit Service db8eaa
	return snd_pcm_write_areas(pcm, NULL, 0, size, snd_pcm_null_xfer_areas);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_writen(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
Packit Service db8eaa
{
Packit Service db8eaa
	return snd_pcm_write_areas(pcm, NULL, 0, size, snd_pcm_null_xfer_areas);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_readi(snd_pcm_t *pcm, void *buffer ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
Packit Service db8eaa
{
Packit Service db8eaa
	return snd_pcm_read_areas(pcm, NULL, 0, size, snd_pcm_null_xfer_areas);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_readn(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
Packit Service db8eaa
{
Packit Service db8eaa
	return snd_pcm_read_areas(pcm, NULL, 0, size, snd_pcm_null_xfer_areas);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_sframes_t snd_pcm_null_mmap_commit(snd_pcm_t *pcm,
Packit Service db8eaa
						  snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
Packit Service db8eaa
						  snd_pcm_uframes_t size)
Packit Service db8eaa
{
Packit Service db8eaa
	return snd_pcm_null_forward(pcm, size);
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_hw_refine(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params)
Packit Service db8eaa
{
Packit Service db8eaa
	int err;
Packit Service db8eaa
Packit Service db8eaa
	/* Do not return a period size of 0 because for example portaudio cannot
Packit Service db8eaa
	 * handle it.
Packit Service db8eaa
	 */
Packit Service db8eaa
	err = _snd_pcm_hw_param_set_min(params, SND_PCM_HW_PARAM_PERIOD_SIZE, 1,
Packit Service db8eaa
					0);
Packit Service db8eaa
	if (err < 0)
Packit Service db8eaa
		return err;
Packit Service db8eaa
Packit Service db8eaa
	err = snd_pcm_hw_refine_soft(pcm, params);
Packit Service db8eaa
	params->info = SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID |
Packit Service db8eaa
		       SND_PCM_INFO_RESUME | SND_PCM_INFO_PAUSE;
Packit Service db8eaa
	params->fifo_size = 0;
Packit Service db8eaa
	return err;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_hw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t * params ATTRIBUTE_UNUSED)
Packit Service db8eaa
{
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_hw_free(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
Packit Service db8eaa
{
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_pcm_null_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t * params ATTRIBUTE_UNUSED)
Packit Service db8eaa
{
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_chmap_query_t **snd_pcm_null_query_chmaps(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
Packit Service db8eaa
	if (null->chmap)
Packit Service db8eaa
		return _snd_pcm_copy_chmap_query(null->chmap);
Packit Service db8eaa
	return NULL;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static snd_pcm_chmap_t *snd_pcm_null_get_chmap(snd_pcm_t *pcm)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_null_t *null = pcm->private_data;
Packit Service db8eaa
Packit Service db8eaa
	if (null->chmap)
Packit Service db8eaa
		return _snd_pcm_choose_fixed_chmap(pcm, null->chmap);
Packit Service db8eaa
	return NULL;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static void snd_pcm_null_dump(snd_pcm_t *pcm, snd_output_t *out)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_output_printf(out, "Null PCM\n");
Packit Service db8eaa
	if (pcm->setup) {
Packit Service db8eaa
		snd_output_printf(out, "Its setup is:\n");
Packit Service db8eaa
		snd_pcm_dump_setup(pcm, out);
Packit Service db8eaa
	}
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static const snd_pcm_ops_t snd_pcm_null_ops = {
Packit Service db8eaa
	.close = snd_pcm_null_close,
Packit Service db8eaa
	.info = snd_pcm_null_info,
Packit Service db8eaa
	.hw_refine = snd_pcm_null_hw_refine,
Packit Service db8eaa
	.hw_params = snd_pcm_null_hw_params,
Packit Service db8eaa
	.hw_free = snd_pcm_null_hw_free,
Packit Service db8eaa
	.sw_params = snd_pcm_null_sw_params,
Packit Service db8eaa
	.channel_info = snd_pcm_generic_channel_info,
Packit Service db8eaa
	.dump = snd_pcm_null_dump,
Packit Service db8eaa
	.nonblock = snd_pcm_null_nonblock,
Packit Service db8eaa
	.async = snd_pcm_null_async,
Packit Service db8eaa
	.mmap = snd_pcm_generic_mmap,
Packit Service db8eaa
	.munmap = snd_pcm_generic_munmap,
Packit Service db8eaa
	.query_chmaps = snd_pcm_null_query_chmaps,
Packit Service db8eaa
	.get_chmap = snd_pcm_null_get_chmap,
Packit Service db8eaa
	.set_chmap = NULL,
Packit Service db8eaa
};
Packit Service db8eaa
Packit Service db8eaa
static const snd_pcm_fast_ops_t snd_pcm_null_fast_ops = {
Packit Service db8eaa
	.status = snd_pcm_null_status,
Packit Service db8eaa
	.state = snd_pcm_null_state,
Packit Service db8eaa
	.hwsync = snd_pcm_null_hwsync,
Packit Service db8eaa
	.delay = snd_pcm_null_delay,
Packit Service db8eaa
	.prepare = snd_pcm_null_prepare,
Packit Service db8eaa
	.reset = snd_pcm_null_reset,
Packit Service db8eaa
	.start = snd_pcm_null_start,
Packit Service db8eaa
	.drop = snd_pcm_null_drop,
Packit Service db8eaa
	.drain = snd_pcm_null_drain,
Packit Service db8eaa
	.pause = snd_pcm_null_pause,
Packit Service db8eaa
	.rewindable = snd_pcm_null_rewindable,
Packit Service db8eaa
	.rewind = snd_pcm_null_rewind,
Packit Service db8eaa
	.forwardable = snd_pcm_null_forwardable,
Packit Service db8eaa
	.forward = snd_pcm_null_forward,
Packit Service db8eaa
	.resume = snd_pcm_null_resume,
Packit Service db8eaa
	.writei = snd_pcm_null_writei,
Packit Service db8eaa
	.writen = snd_pcm_null_writen,
Packit Service db8eaa
	.readi = snd_pcm_null_readi,
Packit Service db8eaa
	.readn = snd_pcm_null_readn,
Packit Service db8eaa
	.avail_update = snd_pcm_null_avail_update,
Packit Service db8eaa
	.mmap_commit = snd_pcm_null_mmap_commit,
Packit Service db8eaa
	.htimestamp = snd_pcm_generic_real_htimestamp,
Packit Service db8eaa
};
Packit Service db8eaa
Packit Service db8eaa
/**
Packit Service db8eaa
 * \brief Creates a new null PCM
Packit Service db8eaa
 * \param pcmp Returns created PCM handle
Packit Service db8eaa
 * \param name Name of PCM
Packit Service db8eaa
 * \param stream Stream type
Packit Service db8eaa
 * \param mode Stream mode
Packit Service db8eaa
 * \retval zero on success otherwise a negative error code
Packit Service db8eaa
 * \warning Using of this function might be dangerous in the sense
Packit Service db8eaa
 *          of compatibility reasons. The prototype might be freely
Packit Service db8eaa
 *          changed in future.
Packit Service db8eaa
 */
Packit Service db8eaa
int snd_pcm_null_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_pcm_t *pcm;
Packit Service db8eaa
	snd_pcm_null_t *null;
Packit Service db8eaa
	int fd;
Packit Service db8eaa
	int err;
Packit Service db8eaa
	assert(pcmp);
Packit Service db8eaa
	if (stream == SND_PCM_STREAM_PLAYBACK) {
Packit Service db8eaa
		fd = open("/dev/null", O_WRONLY);
Packit Service db8eaa
		if (fd < 0) {
Packit Service db8eaa
			SYSERR("Cannot open /dev/null");
Packit Service db8eaa
			return -errno;
Packit Service db8eaa
		}
Packit Service db8eaa
	} else {
Packit Service db8eaa
		fd = open("/dev/full", O_RDONLY);
Packit Service db8eaa
		if (fd < 0) {
Packit Service db8eaa
			SYSERR("Cannot open /dev/full");
Packit Service db8eaa
			return -errno;
Packit Service db8eaa
		}
Packit Service db8eaa
	}
Packit Service db8eaa
	null = calloc(1, sizeof(snd_pcm_null_t));
Packit Service db8eaa
	if (!null) {
Packit Service db8eaa
		close(fd);
Packit Service db8eaa
		return -ENOMEM;
Packit Service db8eaa
	}
Packit Service db8eaa
	null->poll_fd = fd;
Packit Service db8eaa
	null->state = SND_PCM_STATE_OPEN;
Packit Service db8eaa
	
Packit Service db8eaa
	err = snd_pcm_new(&pcm, SND_PCM_TYPE_NULL, name, stream, mode);
Packit Service db8eaa
	if (err < 0) {
Packit Service db8eaa
		close(fd);
Packit Service db8eaa
		free(null);
Packit Service db8eaa
		return err;
Packit Service db8eaa
	}
Packit Service db8eaa
	pcm->ops = &snd_pcm_null_ops;
Packit Service db8eaa
	pcm->fast_ops = &snd_pcm_null_fast_ops;
Packit Service db8eaa
	pcm->private_data = null;
Packit Service db8eaa
	pcm->poll_fd = fd;
Packit Service db8eaa
	pcm->poll_events = stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN;
Packit Service db8eaa
	snd_pcm_set_hw_ptr(pcm, &null->hw_ptr, -1, 0);
Packit Service db8eaa
	snd_pcm_set_appl_ptr(pcm, &null->appl_ptr, -1, 0);
Packit Service db8eaa
	*pcmp = pcm;
Packit Service db8eaa
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
/*! \page pcm_plugins
Packit Service db8eaa
Packit Service db8eaa
\section pcm_plugins_null Plugin: Null
Packit Service db8eaa
Packit Service db8eaa
This plugin discards contents of a PCM stream or creates a stream with zero
Packit Service db8eaa
samples.
Packit Service db8eaa
Packit Service db8eaa
Note: This implementation uses devices /dev/null (playback, must be writable)
Packit Service db8eaa
and /dev/full (capture, must be readable).
Packit Service db8eaa
Packit Service db8eaa
\code
Packit Service db8eaa
pcm.name {
Packit Service db8eaa
        type null               # Null PCM
Packit Service db8eaa
	[chmap MAP]		# Provide channel maps; MAP is a string array
Packit Service db8eaa
}
Packit Service db8eaa
\endcode
Packit Service db8eaa
Packit Service db8eaa
\subsection pcm_plugins_null_funcref Function reference
Packit Service db8eaa
Packit Service db8eaa
    Packit Service db8eaa
      
  • snd_pcm_null_open()
  • Packit Service db8eaa
      
  • _snd_pcm_null_open()
  • Packit Service db8eaa
    Packit Service db8eaa
    Packit Service db8eaa
    */
    Packit Service db8eaa
    Packit Service db8eaa
    /**
    Packit Service db8eaa
     * \brief Creates a new Null PCM
    Packit Service db8eaa
     * \param pcmp Returns created PCM handle
    Packit Service db8eaa
     * \param name Name of PCM
    Packit Service db8eaa
     * \param root Root configuration node
    Packit Service db8eaa
     * \param conf Configuration node with Null PCM description
    Packit Service db8eaa
     * \param stream Stream type
    Packit Service db8eaa
     * \param mode Stream mode
    Packit Service db8eaa
     * \retval zero on success otherwise a negative error code
    Packit Service db8eaa
     * \warning Using of this function might be dangerous in the sense
    Packit Service db8eaa
     *          of compatibility reasons. The prototype might be freely
    Packit Service db8eaa
     *          changed in future.
    Packit Service db8eaa
     */
    Packit Service db8eaa
    int _snd_pcm_null_open(snd_pcm_t **pcmp, const char *name,
    Packit Service db8eaa
    		       snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf, 
    Packit Service db8eaa
    		       snd_pcm_stream_t stream, int mode)
    Packit Service db8eaa
    {
    Packit Service db8eaa
    	snd_config_iterator_t i, next;
    Packit Service db8eaa
    	snd_pcm_null_t *null;
    Packit Service db8eaa
    	snd_pcm_chmap_query_t **chmap = NULL;
    Packit Service db8eaa
    	int err;
    Packit Service db8eaa
    Packit Service db8eaa
    	snd_config_for_each(i, next, conf) {
    Packit Service db8eaa
    		snd_config_t *n = snd_config_iterator_entry(i);
    Packit Service db8eaa
    		const char *id;
    Packit Service db8eaa
    		if (snd_config_get_id(n, &id) < 0)
    Packit Service db8eaa
    			continue;
    Packit Service db8eaa
    		if (snd_pcm_conf_generic_id(id))
    Packit Service db8eaa
    			continue;
    Packit Service db8eaa
    		if (strcmp(id, "chmap") == 0) {
    Packit Service db8eaa
    			snd_pcm_free_chmaps(chmap);
    Packit Service db8eaa
    			chmap = _snd_pcm_parse_config_chmaps(n);
    Packit Service db8eaa
    			if (!chmap) {
    Packit Service db8eaa
    				SNDERR("Invalid channel map for %s", id);
    Packit Service db8eaa
    				return -EINVAL;
    Packit Service db8eaa
    			}
    Packit Service db8eaa
    			continue;
    Packit Service db8eaa
    		}
    Packit Service db8eaa
    		SNDERR("Unknown field %s", id);
    Packit Service db8eaa
    		snd_pcm_free_chmaps(chmap);
    Packit Service db8eaa
    		return -EINVAL;
    Packit Service db8eaa
    	}
    Packit Service db8eaa
    	err = snd_pcm_null_open(pcmp, name, stream, mode);
    Packit Service db8eaa
    	if (err < 0) {
    Packit Service db8eaa
    		snd_pcm_free_chmaps(chmap);
    Packit Service db8eaa
    		return err;
    Packit Service db8eaa
    	}
    Packit Service db8eaa
    Packit Service db8eaa
    	null = (*pcmp)->private_data;
    Packit Service db8eaa
    	null->chmap = chmap;
    Packit Service db8eaa
    	return 0;
    Packit Service db8eaa
    }
    Packit Service db8eaa
    #ifndef DOC_HIDDEN
    Packit Service db8eaa
    SND_DLSYM_BUILD_VERSION(_snd_pcm_null_open, SND_PCM_DLSYM_VERSION);
    Packit Service db8eaa
    #endif