From 41398ceb9ceeb0b97d243c6ee63831260e570010 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 30 May 2005 11:57:26 +0000 Subject: [PATCH] removed ordinary stuff --- include/mixer_ordinary.h | 219 ------- include/pcm_ordinary.h | 145 ----- src/Makefile.am | 2 +- src/ordinary_mixer/Makefile.am | 13 - src/ordinary_mixer/ordinary_mixer.c | 565 ----------------- src/ordinary_pcm/Makefile.am | 13 - src/ordinary_pcm/ordinary_pcm.c | 926 ---------------------------- 7 files changed, 1 insertion(+), 1882 deletions(-) delete mode 100644 include/mixer_ordinary.h delete mode 100644 include/pcm_ordinary.h delete mode 100644 src/ordinary_mixer/Makefile.am delete mode 100644 src/ordinary_mixer/ordinary_mixer.c delete mode 100644 src/ordinary_pcm/Makefile.am delete mode 100644 src/ordinary_pcm/ordinary_pcm.c diff --git a/include/mixer_ordinary.h b/include/mixer_ordinary.h deleted file mode 100644 index c32da09e..00000000 --- a/include/mixer_ordinary.h +++ /dev/null @@ -1,219 +0,0 @@ -/** - * \file include/mixer_ordinary.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \date 2003 - * - * Application interface library for the ALSA driver. - * See the \ref mixer_ordinary page for more details. - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_MIXER_SIMPLE_H -#define __ALSA_MIXER_SIMPLE_H - -#include - -/* - * Abbreviations: - * - * FLVOL - Front Left Volume (0-1000) - * FCLVOL - Front Center Left Volume (0-1000) - * FCVOL - Front Center Volume (0-1000) - * FCRVOL - Front Center Right Volume (0-1000) - * FRVOL - Front Right Volume (0-1000) - * FSLVOL - Front Side Left Volume (0-1000) - * FSRVOL - Front Side Right Volume (0-1000) - * RSLVOL - Rear Side Left Volume (0-1000) - * RSRVOL - Rear Side Right Volume (0-1000) - * RLVOL - Rear Left Volume (0-1000) - * RCVOL - Rear Center Volume (0-1000) - * RRVOL - Rear Right Volume (0-1000) - * LFEVOL - Low Frequency Effects (Subwoofer) Volume (0-1000) - * OVRVOL - Overhead Volume (0-1000) - */ - -/** Ordinary Mixer I/O type */ -enum sndo_mixer_io_type { - - /* - * playback section - */ - - /* Master */ - SNDO_MIO_MASTER_FLVOL = 0 * 0x40, - SNDO_MIO_MASTER_FCLVOL, - SNDO_MIO_MASTER_FCVOL, - SNDO_MIO_MASTER_FCRVOL, - SNDO_MIO_MASTER_FRVOL, - SNDO_MIO_MASTER_FSLVOL, - SNDO_MIO_MASTER_FSRVOL, - SNDO_MIO_MASTER_RSLVOL, - SNDO_MIO_MASTER_RSRVOL, - SNDO_MIO_MASTER_RLVOL, - SNDO_MIO_MASTER_RCVOL, - SNDO_MIO_MASTER_RRVOL, - SNDO_MIO_MASTER_LFEVOL, - SNDO_MIO_MASTER_OVRVOL, - - /* PCM */ - SNDO_MIO_PCM_FLVOL = 1 * 0x40, - SNDO_MIO_PCM_FCLVOL, - SNDO_MIO_PCM_FCVOL, - SNDO_MIO_PCM_FCRVOL, - SNDO_MIO_PCM_FRVOL, - SNDO_MIO_PCM_FSLVOL, - SNDO_MIO_PCM_FSRVOL, - SNDO_MIO_PCM_RSLVOL, - SNDO_MIO_PCM_RSRVOL, - SNDO_MIO_PCM_RLVOL, - SNDO_MIO_PCM_RCVOL, - SNDO_MIO_PCM_RRVOL, - SNDO_MIO_PCM_LFEVOL, - SNDO_MIO_PCM_OVRVOL, - - /* LINE */ - SNDO_MIO_LINE_FLVOL = 2 * 0x40, - SNDO_MIO_LINE_FCLVOL, - SNDO_MIO_LINE_FCVOL, - SNDO_MIO_LINE_FCRVOL, - SNDO_MIO_LINE_FRVOL, - SNDO_MIO_LINE_FSLVOL, - SNDO_MIO_LINE_FSRVOL, - SNDO_MIO_LINE_RSLVOL, - SNDO_MIO_LINE_RSRVOL, - SNDO_MIO_LINE_RLVOL, - SNDO_MIO_LINE_RCVOL, - SNDO_MIO_LINE_RRVOL, - SNDO_MIO_LINE_LFEVOL, - SNDO_MIO_LINE_OVRVOL, - - /* MIC */ - SNDO_MIO_MIC_FLVOL = 3 * 0x40, - SNDO_MIO_MIC_FCLVOL, - SNDO_MIO_MIC_FCVOL, - SNDO_MIO_MIC_FCRVOL, - SNDO_MIO_MIC_FRVOL, - SNDO_MIO_MIC_FSLVOL, - SNDO_MIO_MIC_FSRVOL, - SNDO_MIO_MIC_RSLVOL, - SNDO_MIO_MIC_RSRVOL, - SNDO_MIO_MIC_RLVOL, - SNDO_MIO_MIC_RCVOL, - SNDO_MIO_MIC_RRVOL, - SNDO_MIO_MIC_LFEVOL, - SNDO_MIO_MIC_OVRVOL, - - /* CD */ - SNDO_MIO_CD_FLVOL = 4 * 0x40, - SNDO_MIO_CD_FCLVOL, - SNDO_MIO_CD_FCVOL, - SNDO_MIO_CD_FCRVOL, - SNDO_MIO_CD_FRVOL, - SNDO_MIO_CD_FSLVOL, - SNDO_MIO_CD_FSRVOL, - SNDO_MIO_CD_RSLVOL, - SNDO_MIO_CD_RSRVOL, - SNDO_MIO_CD_RLVOL, - SNDO_MIO_CD_RCVOL, - SNDO_MIO_CD_RRVOL, - SNDO_MIO_CD_LFEVOL, - SNDO_MIO_CD_OVRVOL, - - /* AUX */ - SNDO_MIO_AUX_FLVOL = 5 * 0x40, - SNDO_MIO_AUX_FCLVOL, - SNDO_MIO_AUX_FCVOL, - SNDO_MIO_AUX_FCRVOL, - SNDO_MIO_AUX_FRVOL, - SNDO_MIO_AUX_FSLVOL, - SNDO_MIO_AUX_FSRVOL, - SNDO_MIO_AUX_RSLVOL, - SNDO_MIO_AUX_RSRVOL, - SNDO_MIO_AUX_RLVOL, - SNDO_MIO_AUX_RCVOL, - SNDO_MIO_AUX_RRVOL, - SNDO_MIO_AUX_LFEVOL, - SNDO_MIO_AUX_OVRVOL, - - /* - * capture section - */ - - /* capture gain */ - SNDO_MIO_CGAIN_FL = 0x8000, - SNDO_MIO_CGAIN_FCL, - SNDO_MIO_CGAIN_FC, - SNDO_MIO_CGAIN_FCR, - SNDO_MIO_CGAIN_FR, - SNDO_MIO_CGAIN_FSL, - SNDO_MIO_CGAIN_FSR, - SNDO_MIO_CGAIN_RSL, - SNDO_MIO_CGAIN_RSR, - SNDO_MIO_CGAIN_RL, - SNDO_MIO_CGAIN_RC, - SNDO_MIO_CGAIN_RR, - SNDO_MIO_CGAIN_LFE, - SNDO_MIO_CGAIN_OVR, - - /* capture source (0 = off, 1 = on) */ - SNDO_MIO_CSOURCE_MIC = 0x8100, - SNDO_MIO_CSOURCE_LINE, - SNDO_MIO_CSOURCE_CD, - SNDO_MIO_CSOURCE_AUX, - SNDO_MIO_CSOURCE_MIX, - - /* misc */ - SNDO_MIO_STEREO = 0x8200, /* (0 = off, 1 = on) standard stereo source, might be converted to use all outputs */ -}; - -typedef struct sndo_mixer sndo_mixer_t; -struct alisp_cfg; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Mixer_ordinary Mixer Ordinary Interface - * See the \ref mixer_ordinary page for more details. - * \{ - */ - -int sndo_mixer_open(sndo_mixer_t **pmixer, const char *playback_name, const char *capture_name, struct alisp_cfg *lconf); -int sndo_mixer_open_pcm(sndo_mixer_t **pmixer, snd_pcm_t *playback_pcm, snd_pcm_t *capture_pcm, struct alisp_cfg *lconf); -int sndo_mixer_close(sndo_mixer_t *mixer); -int sndo_mixer_poll_descriptors_count(sndo_mixer_t *mixer); -int sndo_mixer_poll_descriptors(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int space); -int sndo_mixer_poll_descriptors_revents(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); -int sndo_mixer_io_get_name(enum sndo_mixer_io_type type, char **name); -int sndo_mixer_io_get(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val); -int sndo_mixer_io_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val); -int sndo_mixer_io_try_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val); -int sndo_mixer_io_get_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val); -int sndo_mixer_io_set_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val); -int sndo_mixer_io_try_set_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val); -int sndo_mixer_io_change(sndo_mixer_t *mixer, enum sndo_mixer_io_type *changed, int changed_array_size); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_MIXER_SIMPLE_H */ diff --git a/include/pcm_ordinary.h b/include/pcm_ordinary.h deleted file mode 100644 index 50f8dcf5..00000000 --- a/include/pcm_ordinary.h +++ /dev/null @@ -1,145 +0,0 @@ -/** - * \file include/pcm_ordinary.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \date 2003 - * - * Application interface library for the ALSA driver. - * See the \ref pcm_ordinary page for more details. - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_PCM_ORDINARY_H -#define __ALSA_PCM_ORDINARY_H - -#include - -/** Ordinary PCM latency type */ -enum sndo_pcm_latency_type { - /** normal latency - for standard playback or capture - (estimated latency in one direction 350ms) (default) */ - SNDO_PCM_LATENCY_NORMAL = 0, - /** medium latency - software phones etc. - (estimated latency in one direction maximally 50ms) */ - SNDO_PCM_LATENCY_MEDIUM, - /** realtime latency - realtime applications (effect processors etc.) - (estimated latency in one direction 5ms) */ - SNDO_PCM_LATENCY_REALTIME -}; - -/** Ordinary PCM access type */ -enum sndo_pcm_access_type { - /** interleaved access - channels are interleaved without any gaps among samples (default) */ - SNDO_PCM_ACCESS_INTERLEAVED = 0, - /** noninterleaved access - channels are separate without any gaps among samples */ - SNDO_PCM_ACCESS_NONINTERLEAVED -}; - -/** Ordinary PCM xrun type */ -enum sndo_pcm_xrun_type { - /** driver / library will ignore all xruns, the stream runs forever (default) */ - SNDO_PCM_XRUN_IGNORE = 0, - /** driver / library stops the stream when an xrun occurs */ - SNDO_PCM_XRUN_STOP -}; - -typedef struct sndo_pcm sndo_pcm_t; - -typedef int (sndo_pcm_engine_callback_t)(sndo_pcm_t *pcm); - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup PCM_ordinary PCM Ordinary Interface - * See the \ref pcm_ordinary page for more details. - * \{ - */ - -int sndo_pcm_open(sndo_pcm_t **pcm, const char *playback_name, const char *capture_name, struct alisp_cfg *lconf); -int sndo_pcm_close(sndo_pcm_t *pcm); -int sndo_pcm_poll_descriptors_count(sndo_pcm_t *pcm); -int sndo_pcm_poll_descriptors(sndo_pcm_t *pcm, struct pollfd *pfds, unsigned int space); -int sndo_pcm_start(sndo_pcm_t *pcm); -int sndo_pcm_drop(sndo_pcm_t *pcm); -int sndo_pcm_drain(sndo_pcm_t *pcm); -int sndo_pcm_delay(sndo_pcm_t *pcm, snd_pcm_sframes_t *delayp); -int sndo_pcm_transfer_block(sndo_pcm_t *pcm, snd_pcm_uframes_t *tblock); -int sndo_pcm_resume(sndo_pcm_t *pcm); -int sndo_pcm_wait(sndo_pcm_t *pcm, int timeout); -snd_pcm_t *sndo_pcm_raw_playback(sndo_pcm_t *pcm); -snd_pcm_t *sndo_pcm_raw_capture(sndo_pcm_t *pcm); - -/** - * \defgroup PCM_ordinary_params Parameters Functions - * \ingroup PCM_ordinary - * See the \ref pcm_ordinary page for more details. - * \{ - */ - -int sndo_pcm_param_reset(sndo_pcm_t *pcm); -int sndo_pcm_param_access(sndo_pcm_t *pcm, enum sndo_pcm_access_type access); -int sndo_pcm_param_rate(sndo_pcm_t *pcm, unsigned int rate, unsigned int *used_rate); -int sndo_pcm_param_channels(sndo_pcm_t *pcm, unsigned int channels); -int sndo_pcm_param_format(sndo_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_subformat_t subformat); -int sndo_pcm_param_latency(sndo_pcm_t *pcm, enum sndo_pcm_latency_type latency, snd_pcm_uframes_t *used_latency); -int sndo_pcm_param_xrun(sndo_pcm_t *pcm, enum sndo_pcm_xrun_type xrun); - -/** \} */ - -/** - * \defgroup PCM_ordinary_access Ring Buffer I/O Functions - * \ingroup PCM_ordinary - * See the \ref pcm_ordinary page for more details. - * \{ - */ - -/* playback */ -int sndo_pcm_pio_ibegin(sndo_pcm_t *pcm, void **ring_buffer, snd_pcm_uframes_t *frames); -snd_pcm_sframes_t sndo_pcm_pio_iend(sndo_pcm_t *pcm, snd_pcm_uframes_t frames); -int sndo_pcm_pio_nbegin(sndo_pcm_t *pcm, void ***ring_buffer, snd_pcm_uframes_t *frames); -snd_pcm_sframes_t sndo_pcm_pio_nend(sndo_pcm_t *pcm, snd_pcm_uframes_t frames); -/* capture */ -int sndo_pcm_cio_ibegin(sndo_pcm_t *pcm, void **ring_buffer, snd_pcm_uframes_t *frames); -snd_pcm_sframes_t sndo_pcm_cio_iend(sndo_pcm_t *pcm, snd_pcm_uframes_t frames); -int sndo_pcm_cio_nbegin(sndo_pcm_t *pcm, void ***ring_buffer, snd_pcm_uframes_t *frames); -snd_pcm_sframes_t sndo_pcm_cio_nend(sndo_pcm_t *pcm, snd_pcm_uframes_t frames); - -/** \} */ - -/** - * \defgroup PCM_ordinary_engine Callback like engine - * \ingroup PCM_ordinary - * See the \ref pcm_ordinary page for more details. - * \{ - */ - -int sndo_pcm_set_private_data(sndo_pcm_t *pcm, void *private_data); -int sndo_pcm_get_private_data(sndo_pcm_t *pcm, void **private_data); -int sndo_pcm_engine(sndo_pcm_t *pcm, - sndo_pcm_engine_callback_t *playback, - sndo_pcm_engine_callback_t *capture); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_PCM_ORDINARY_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 4c1f9d0a..1e787e60 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS=control mixer ordinary_mixer pcm ordinary_pcm rawmidi timer hwdep seq instr compat conf alisp +SUBDIRS=control mixer pcm rawmidi timer hwdep seq instr compat conf alisp EXTRA_DIST=Versions COMPATNUM=@LIBTOOL_VERSION_INFO@ diff --git a/src/ordinary_mixer/Makefile.am b/src/ordinary_mixer/Makefile.am deleted file mode 100644 index 9f3c579d..00000000 --- a/src/ordinary_mixer/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -#SUBDIRS = -#DIST_SUBDIRS = - -EXTRA_LTLIBRARIES = libordinarymixer.la - -libordinarymixer_la_SOURCES = ordinary_mixer.c -#noinst_HEADERS = - -alsadir = $(datadir)/alsa - -all: libordinarymixer.la - -INCLUDES=-I$(top_srcdir)/include diff --git a/src/ordinary_mixer/ordinary_mixer.c b/src/ordinary_mixer/ordinary_mixer.c deleted file mode 100644 index 4f09d1ca..00000000 --- a/src/ordinary_mixer/ordinary_mixer.c +++ /dev/null @@ -1,565 +0,0 @@ -/** - * \file ordinary_mixer/ordinary_mixer.c - * \ingroup Mixer_ordinary - * \brief Ordinary mixer interface - * \author Jaroslav Kysela - * \date 2003,2004 - * - * Ordinary mixer interface is a high level abtraction for soundcard's - * mixing. - * - * See the \ref Mixer_ordinary page for more details. - */ -/* - * Ordinary Mixer Interface - main file - * Copyright (c) 2003 by Jaroslav Kysela - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/*! \page Mixer_ordinary Ordinary mixer interface - -

Write something here

- -\section Mixer_ordinary_overview - -Write something here - -*/ -/** - * \example ../test/ordinary_mixer.c - * \anchor example_ordinary_mixer - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "local.h" -#include "alisp.h" -#include "mixer_ordinary.h" - -struct sndo_mixer { - struct alisp_cfg *cfg; - struct alisp_instance *alisp; - int hctl_count; - snd_hctl_t **hctl; - int _free_cfg; -}; - -int sndo_mixer_open1(sndo_mixer_t **pmixer, - const char *lisp_fcn, - const char *lisp_fmt, - const void *parg, - const void *carg, - struct alisp_cfg *lconf) -{ - struct alisp_cfg *cfg = lconf; - struct alisp_instance *alisp; - struct alisp_seq_iterator *iterator; - sndo_mixer_t *mixer; - int err, count; - long val; - - *pmixer = NULL; - if (cfg == NULL) { - char *file; - snd_input_t *input; - file = getenv("ALSA_ORDINARY_MIXER"); - if (!file) - file = DATADIR "/alsa/sndo-mixer.alisp"; - if ((err = snd_input_stdio_open(&input, file, "r")) < 0) { - SNDERR("unable to open alisp file '%s'", file); - return err; - } - cfg = alsa_lisp_default_cfg(input); - if (cfg == NULL) - return -ENOMEM; - cfg->warning = 1; -#if 0 - cfg->debug = 1; - cfg->verbose = 1; -#endif - } - err = alsa_lisp(cfg, &alisp); - if (err < 0) - goto __error; - err = alsa_lisp_function(alisp, &iterator, lisp_fcn, lisp_fmt, parg, carg); - if (err < 0) { - alsa_lisp_free(alisp); - goto __error; - } - err = alsa_lisp_seq_integer(iterator, &val); - if (err == 0 && val < 0) - err = val; - alsa_lisp_result_free(alisp, iterator); - if (err < 0) { - alsa_lisp_free(alisp); - goto __error; - } - count = 0; - if (alsa_lisp_seq_first(alisp, "hctls", &iterator) == 0) { - count = alsa_lisp_seq_count(iterator); - if (count < 0) - count = 0; - } - mixer = malloc(sizeof(sndo_mixer_t) + count * sizeof(snd_hctl_t *)); - if (mixer == NULL) { - alsa_lisp_free(alisp); - err = -ENOMEM; - goto __error; - } - memset(mixer, 0, sizeof(sndo_mixer_t)); - if (count > 0) { - mixer->hctl = (snd_hctl_t **)(mixer + 1); - do { - if (alsa_lisp_seq_pointer(iterator, "hctl", (void **)&mixer->hctl[mixer->hctl_count++])) - break; - } while (mixer->hctl_count < count && alsa_lisp_seq_next(&iterator) == 0); - if (mixer->hctl_count < count) { - mixer->hctl = NULL; - mixer->hctl_count = 0; - } - } - mixer->alisp = alisp; - mixer->cfg = cfg; - mixer->_free_cfg = cfg != lconf; - *pmixer = mixer; - return 0; - __error: - if (cfg != lconf) - alsa_lisp_default_cfg_free(cfg); - return err; -} - -/** - * \brief Opens a ordinary mixer instance - * \param pmixer Returned ordinary mixer handle - * \param playback_name name for playback HCTL communication - * \param capture_name name for capture HCTL communication - * \param lconf Local configuration (might be NULL - use global configuration) - * \return 0 on success otherwise a negative error code - */ -int sndo_mixer_open(sndo_mixer_t **pmixer, - const char *playback_name, - const char *capture_name, - struct alisp_cfg *lconf) -{ - return sndo_mixer_open1(pmixer, "sndo_mixer_open", "%s%s", playback_name, capture_name, lconf); -} - - -/** - * \brief Opens a ordinary mixer instance - * \param pmixer Returned ordinary mixer handle - * \param playback_pcm handle of the playback PCM - * \param capture_pcm handle of the capture PCM - * \param lconf Local configuration (might be NULL - use global configuration) - * \return 0 on success otherwise a negative error code - */ -int sndo_mixer_open_pcm(sndo_mixer_t **pmixer, - snd_pcm_t *playback_pcm, - snd_pcm_t *capture_pcm, - struct alisp_cfg *lconf) -{ - return sndo_mixer_open1(pmixer, "sndo_mixer_open_pcm", "%ppcm%ppcm", playback_pcm, capture_pcm, lconf); -} - -/** - * \brief Closes a ordinary mixer instance - * \param mixer Ordinary mixer handle to close - * \return 0 on success otherwise a negative error code - */ -int sndo_mixer_close(sndo_mixer_t *mixer) -{ - int res; - - res = alsa_lisp_function(mixer->alisp, NULL, "sndo_mixer_close", "n"); - alsa_lisp_free(mixer->alisp); - if (mixer->_free_cfg) - alsa_lisp_default_cfg_free(mixer->cfg); - free(mixer); - return res; -} - -/** - * \brief get count of poll descriptors for ordinary mixer handle - * \param mixer ordinary mixer handle - * \return count of poll descriptors - */ -int sndo_mixer_poll_descriptors_count(sndo_mixer_t *mixer) -{ - int idx, err, res = -EIO; - - if (mixer->hctl_count > 0) { - for (idx = 0; idx < mixer->hctl_count; idx++) { - err = snd_hctl_poll_descriptors_count(mixer->hctl[idx]); - if (err < 0) - return err; - res += err; - } - } else { - struct alisp_seq_iterator *result; - long val; - err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_poll_descriptors_count", "n"); - if (err < 0) - return err; - err = alsa_lisp_seq_integer(result, &val); - return err < 0 ? err : val; - } - return res; -} - -/** - * \brief get poll descriptors - * \param mixer ordinary mixer handle - * \param pfds array of poll descriptors - * \param space space in the poll descriptor array - * \return count of filled descriptors - */ -int sndo_mixer_poll_descriptors(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int space) -{ - int err, idx, res; - - if (mixer->hctl_count > 0) { - for (idx = res = 0; idx < mixer->hctl_count && space > 0; idx++) { - err = snd_hctl_poll_descriptors(mixer->hctl[idx], pfds, space); - if (err < 0) - return err; - res += err; - space -= err; - } - return res; - } else { - struct alisp_seq_iterator *result; - long val; - err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_poll_descriptors", "%i", space); - if (err < 0) - return err; - assert(0); /* FIXME: pass pfds to application */ - err = alsa_lisp_seq_integer(result, &val); - return err < 0 ? err : val; - } -} - -/** - * \brief get returned events from poll descriptors - * \param mixer ordinary mixer handle - * \param pfds array of poll descriptors - * \param nfds count of poll descriptors - * \param revents returned events - * \return zero if success, otherwise a negative error code - */ -int sndo_mixer_poll_descriptors_revents(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents) -{ - int err, idx, count, res; - - if (mixer->hctl_count > 0) { - for (idx = res = 0; idx < mixer->hctl_count && nfds > 0; idx++) { - err = snd_hctl_poll_descriptors_count(mixer->hctl[idx]); - if (err < 0) - return err; - count = err; - if (nfds < (unsigned int)err) - return -EINVAL; - err = snd_hctl_poll_descriptors_revents(mixer->hctl[idx], pfds, count, revents); - if (err < 0) - return err; - if (err != count) - return -EINVAL; - pfds += count; - nfds -= err; - revents += count; - res += count; - } - return res; - } else { - struct alisp_seq_iterator *result; - long val, tmp; - - assert(0); /* FIXME: pass pfds to alisp too */ - err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_poll_descriptors_revents", "%i", nfds); - if (err < 0) - return err; - err = alsa_lisp_seq_integer(result, &val); - if (err >= 0 && alsa_lisp_seq_count(result) > 1) { - alsa_lisp_seq_next(&result); - err = alsa_lisp_seq_integer(result, &tmp); - *revents = tmp; - } else { - *revents = 0; - } - return err < 0 ? err : val; - } -} - -#define IOLINES 6 - -static const char *name_table1[] = { - "Master", - "PCM", - "Line", - "Mic" - "CD", - "AUX" -}; - -#define SPEAKERS 14 - -static const char *name_table2[] = { - "Front Left", - "Front Center Left", - "Front Center", - "Front Center Right", - "Front Right", - "Front Side Left", - "Front Side Right", - "Rear Side Left", - "Rear Side Right", - "Rear Left", - "Rear Center", - "Rear Right", - "LFE (Subwoofer)", - "Overhead" -}; - -#define CSOURCES 5 - -static const char *name_table3[] = { - "Mic", - "Line", - "CD", - "AUX", - "Mix", -}; - -static int compose_string(char **result, const char *s1, const char *s2, const char *s3, const char *s4) -{ - int len = strlen(s1) + strlen(s2) + strlen(s3) + strlen(s4); - *result = malloc(len + 1); - if (*result == NULL) - return -ENOMEM; - strcpy(*result, s1); - strcat(*result, s2); - strcat(*result, s3); - strcat(*result, s4); - return 0; -} - -/** - * \brief get ordinary mixer io control value - * \param mixer ordinary mixer handle - * \param type io type - * \param val returned value - * \return zero if success, otherwise a negative error code - */ -int sndo_mixer_io_get_name(enum sndo_mixer_io_type type, char **name) -{ - if (type < IOLINES * 0x40) { - int tmp = type / 0x40; - type %= 0x40; - if (type < SPEAKERS) - return compose_string(name, name_table1[tmp], " ", name_table2[type], " Volume"); - } else if (type >= SNDO_MIO_CGAIN_FL && type < SNDO_MIO_CGAIN_FL + SPEAKERS) { - return compose_string(name, "Capture Gain ", name_table2[type - SNDO_MIO_CGAIN_FL], "", ""); - } else if (type >= SNDO_MIO_CSOURCE_MIC && type < SNDO_MIO_CSOURCE_MIC + CSOURCES) { - return compose_string(name, "Capture Source ", name_table3[type - SNDO_MIO_CSOURCE_MIC], "", ""); - } - return -ENOENT; -} - -/** - * \brief get ordinary mixer io control value - * \param mixer ordinary mixer handle - * \param type io type - * \param val returned value - * \return zero if success, otherwise a negative error code - */ -int sndo_mixer_io_get(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val) -{ - struct alisp_seq_iterator *result; - long val1; - int err; - - err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_set", "%i", type); - if (err < 0) - return err; - err = alsa_lisp_seq_integer(result, &val1); - if (err < 0) - return err; - *val = val1; - return 0; -} - -/** - * \brief set ordinary mixer io control value - * \param mixer ordinary mixer handle - * \param type io type - * \param val desired value - * \return zero if success, otherwise a negative error code - */ -int sndo_mixer_io_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val) -{ - struct alisp_seq_iterator *result; - long val1; - int err; - - err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_set", "%i%i", type, *val); - if (err < 0) - return err; - err = alsa_lisp_seq_integer(result, &val1); - if (err < 0) - return err; - *val = val1; - return 0; -} - -/** - * \brief try to set ordinary mixer io control value - * \param mixer ordinary mixer handle - * \param type io type - * \param val desired value - * \return zero if success, otherwise a negative error code - * - * This function does not update the value. - * It only returns the real value which will be set. - */ -int sndo_mixer_io_try_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val) -{ - struct alisp_seq_iterator *result; - long val1; - int err; - - err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_try_set", "%i%i", type, *val); - if (err < 0) - return err; - err = alsa_lisp_seq_integer(result, &val1); - if (err < 0) - return err; - *val = val1; - return 0; -} - -/** - * \brief get ordinary mixer io control value in dB (decibel units) - * \param mixer ordinary mixer handle - * \param type io type - * \param val returned value in dB - * \return zero if success, otherwise a negative error code - */ -int sndo_mixer_io_get_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val) -{ - struct alisp_seq_iterator *result; - long val1; - int err; - - err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_set_dB", "%i", type); - if (err < 0) - return err; - err = alsa_lisp_seq_integer(result, &val1); - if (err < 0) - return err; - *val = val1; - return 0; -} - -/** - * \brief set ordinary mixer io control value in dB (decibel units) - * \param mixer ordinary mixer handle - * \param type io type - * \param val desired value in dB - * \return zero if success, otherwise a negative error code - */ -int sndo_mixer_io_set_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val) -{ - struct alisp_seq_iterator *result; - long val1; - int err; - - err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_set", "%i%i", type, *val); - if (err < 0) - return err; - err = alsa_lisp_seq_integer(result, &val1); - if (err < 0) - return err; - *val = val1; - return 0; -} - -/** - * \brief try to set ordinary mixer io control value in dB (decibel units) - * \param mixer ordinary mixer handle - * \param type io type - * \param val desired and returned value in dB - * \return zero if success, otherwise a negative error code - * - * This function does not update the value. - * It only returns the real value which will be set. - */ -int sndo_mixer_io_try_set_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val) -{ - struct alisp_seq_iterator *result; - long val1; - int err; - - err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_try_set", "%i%i", type, *val); - if (err < 0) - return err; - err = alsa_lisp_seq_integer(result, &val1); - if (err < 0) - return err; - *val = val1; - return 0; -} - -/** - * \brief get ordinary mixer io control change notification - * \param mixer ordinary mixer handle - * \param changed list of changed io types - * \param changed_array_size size of list of changed io types - * \return zero if success, otherwise a negative error code - */ -int sndo_mixer_io_change(sndo_mixer_t *mixer, enum sndo_mixer_io_type *changed, int changed_array_size) -{ - struct alisp_seq_iterator *result; - long val1; - int err; - - err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_change", "%i", changed_array_size); - if (err < 0) - return err; - err = alsa_lisp_seq_integer(result, &val1); - if (err < 0) - return err; - if (val1 < 0) - return val1; - while (changed_array_size-- > 0) { - *changed = val1; - if (!alsa_lisp_seq_next(&result)) - break; - err = alsa_lisp_seq_integer(result, &val1); - if (err < 0) - return err; - } - return 0; -} diff --git a/src/ordinary_pcm/Makefile.am b/src/ordinary_pcm/Makefile.am deleted file mode 100644 index e44b57cf..00000000 --- a/src/ordinary_pcm/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -#SUBDIRS = -#DIST_SUBDIRS = - -EXTRA_LTLIBRARIES = libordinarypcm.la - -libordinarypcm_la_SOURCES = ordinary_pcm.c -#noinst_HEADERS = - -alsadir = $(datadir)/alsa - -all: libordinarypcm.la - -INCLUDES=-I$(top_srcdir)/include diff --git a/src/ordinary_pcm/ordinary_pcm.c b/src/ordinary_pcm/ordinary_pcm.c deleted file mode 100644 index 19aaf23f..00000000 --- a/src/ordinary_pcm/ordinary_pcm.c +++ /dev/null @@ -1,926 +0,0 @@ -/** - * \file ordinary_pcm/ordinary_pcm.c - * \ingroup PCM_ordinary - * \brief Ordinary PCM interface - * \author Jaroslav Kysela - * \date 2003,2004 - * - * Ordinary PCM interface is a high level abtraction for - * digital audio streaming. - * - * See the \ref PCM_ordinary page for more details. - */ -/* - * Ordinary PCM Interface - main file - * Copyright (c) 2003 by Jaroslav Kysela - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/*! \page PCM_ordinary Ordinary PCM interface - -

Write something here

- -\section PCM_ordinary_overview - -Write something here - -*/ -/** - * \example ../test/ordinary_pcm.c - * \anchor example_ordinary_pcm - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "asoundlib.h" -#include "alisp.h" -#include "pcm_ordinary.h" - -struct sndo_pcm { - snd_pcm_t *playback; - snd_pcm_t *capture; - snd_pcm_hw_params_t *p_hw_params; - snd_pcm_hw_params_t *c_hw_params; - snd_pcm_sw_params_t *p_sw_params; - snd_pcm_sw_params_t *c_sw_params; - snd_pcm_t *master; - unsigned int channels; - unsigned int samplebytes; - snd_pcm_uframes_t p_offset; - snd_pcm_uframes_t c_offset; - snd_pcm_uframes_t p_period_size; - snd_pcm_uframes_t c_period_size; - snd_pcm_uframes_t transfer_block; - snd_pcm_uframes_t ring_size; - enum sndo_pcm_latency_type latency; - enum sndo_pcm_xrun_type xrun; - int setting_up; - int initialized; -}; - -static int sndo_pcm_setup(sndo_pcm_t *pcm); -static int sndo_pcm_initialize(sndo_pcm_t *pcm); - -static inline int sndo_pcm_check_setup(sndo_pcm_t *pcm) -{ - if (!pcm->initialized) - return sndo_pcm_initialize(pcm); - return 0; -} - -/** - * \brief Opens a ordinary pcm instance - * \param ppcm Returned ordinary pcm handle - * \param playback_name ASCII identifier of the ordinary pcm handle (playback) - * \param capture_name ASCII identifier of the ordinary pcm handle (capture) - * \param lconf Local configuration (might be NULL - use global configuration) - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_open(sndo_pcm_t **ppcm, - const char *playback_name, - const char *capture_name, - struct alisp_cfg *lconf) -{ - int err = 0; - sndo_pcm_t *pcm; - - assert(ppcm); - assert(playback_name || capture_name); - *ppcm = NULL; - pcm = calloc(1, sizeof(sndo_pcm_t)); - if (pcm == NULL) - return -ENOMEM; - if (playback_name) { - err = snd_pcm_hw_params_malloc(&pcm->p_hw_params); - if (err < 0) - goto __end; - err = snd_pcm_sw_params_malloc(&pcm->p_sw_params); - } - if (capture_name) { - err = snd_pcm_hw_params_malloc(&pcm->c_hw_params); - if (err < 0) - goto __end; - err = snd_pcm_sw_params_malloc(&pcm->p_sw_params); - } - if (err < 0) - goto __end; - if (lconf) { - if (playback_name) { - err = snd_pcm_open_lconf(&pcm->playback, playback_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK, NULL); - if (err < 0) - goto __end; - } - if (capture_name) { - err = snd_pcm_open_lconf(&pcm->capture, playback_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK, NULL); - if (err < 0) - goto __end; - } - } else { - if (playback_name) { - err = snd_pcm_open(&pcm->playback, playback_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); - if (err < 0) - goto __end; - } - if (capture_name) { - err = snd_pcm_open(&pcm->capture, playback_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); - if (err < 0) - goto __end; - } - } - if (pcm->playback && pcm->capture) { - err = snd_pcm_link(pcm->playback, pcm->capture); - if (err < 0) - goto __end; - pcm->master = pcm->playback; - } - __end: - if (err < 0) - sndo_pcm_close(pcm); - return err; -} - -/** - * \brief Closes a ordinary pcm instance - * \param pcm Ordinary pcm handle to close - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_close(sndo_pcm_t *pcm) -{ - int err; - - if (pcm->playback) - err = snd_pcm_close(pcm->playback); - if (pcm->capture) - err = snd_pcm_close(pcm->capture); - if (pcm->p_hw_params) - snd_pcm_hw_params_free(pcm->p_hw_params); - if (pcm->p_sw_params) - snd_pcm_sw_params_free(pcm->p_sw_params); - if (pcm->c_hw_params) - snd_pcm_hw_params_free(pcm->c_hw_params); - if (pcm->c_sw_params) - snd_pcm_sw_params_free(pcm->c_sw_params); - free(pcm); - return 0; -} - -/** - * \brief get count of poll descriptors for ordinary pcm handle - * \param pcm ordinary pcm handle - * \return count of poll descriptors - */ -int sndo_pcm_poll_descriptors_count(sndo_pcm_t *pcm) -{ - int err, res = 0; - - err = snd_pcm_poll_descriptors_count(pcm->playback); - if (err > 0) - res += err; - err = snd_pcm_poll_descriptors_count(pcm->capture); - if (err > 0) - res += err; - return err < 0 ? err : res; -} - -/** - * \brief get poll descriptors - * \param pcm ordinary pcm handle - * \param pfds array of poll descriptors - * \param space space in the poll descriptor array - * \return count of filled descriptors - */ -int sndo_pcm_poll_descriptors(sndo_pcm_t *pcm, struct pollfd *pfds, unsigned int space) -{ - int playback, err, res = 0; - - playback = snd_pcm_poll_descriptors_count(pcm->playback); - if (playback < 0) - return playback; - err = snd_pcm_poll_descriptors(pcm->playback, pfds, (unsigned)playback < space ? (unsigned)playback : space); - if (err < 0) - return err; - res += err; - if ((unsigned)res < space) { - err = snd_pcm_poll_descriptors(pcm->capture, pfds + res, space - res); - if (err < 0) - return err; - res += err; - } - return res; -} - -/** - * \brief get returned events from poll descriptors - * \param pcm ordinary pcm handle - * \param pfds array of poll descriptors - * \param nfds count of poll descriptors - * \param revents returned events - * \return zero if success, otherwise a negative error code - */ -int sndo_pcm_poll_descriptors_revents(sndo_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents) -{ - int playback, err; - unsigned short _revents; - - playback = snd_pcm_poll_descriptors_count(pcm->playback); - if (playback < 0) - return playback; - err = snd_pcm_poll_descriptors_revents(pcm->playback, pfds, nfds < (unsigned)playback ? nfds : (unsigned)playback, revents); - if (err < 0) - return err; - if (nfds > (unsigned)playback) { - err = snd_pcm_poll_descriptors_revents(pcm->capture, pfds + playback, nfds - playback, &_revents); - if (err < 0) - return err; - *revents |= _revents; - } - return 0; -} - -/** - * \brief Start a PCM - * \param pcm ordinary PCM handle - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_start(sndo_pcm_t *pcm) -{ - int err; - - err = sndo_pcm_check_setup(pcm); - if (err < 0) - return err; - /* the streams are linked, so use only one stream */ - return snd_pcm_start(pcm->master); -} - -/** - * \brief Stop a PCM dropping pending frames - * \param pcm ordinary PCM handle - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_drop(sndo_pcm_t *pcm) -{ - /* the streams are linked, so use only one stream */ - return snd_pcm_drop(pcm->master); -} - -/** - * \brief Stop a PCM preserving pending frames - * \param pcm PCM handle - * \return 0 on success otherwise a negative error code - * \retval -ESTRPIPE a suspend event occurred - * - * For playback wait for all pending frames to be played and then stop - * the PCM. - * For capture stop PCM permitting to retrieve residual frames. - */ -int sndo_pcm_drain(sndo_pcm_t *pcm) -{ - /* the streams are linked, so use only one stream */ - return snd_pcm_drain(pcm->master); -} - -/** - * \brief Obtain delay for a running PCM handle - * \param pcm ordinary PCM handle - * \param delayp Returned delay in frames - * \return 0 on success otherwise a negative error code - * - * Delay is distance between current application frame position and - * sound frame position. - * It's positive and less than buffer size in normal situation, - * negative on playback underrun and greater than buffer size on - * capture overrun. - */ -int sndo_pcm_delay(sndo_pcm_t *pcm, snd_pcm_sframes_t *delayp) -{ - int err; - snd_pcm_sframes_t pdelay, cdelay; - - assert(pcm); - assert(delayp); - err = sndo_pcm_check_setup(pcm); - if (err < 0) - return err; - if (pcm->playback) - err = snd_pcm_avail_update(pcm->playback); - if (err >= 0 && pcm->capture) - err = snd_pcm_avail_update(pcm->capture); - if (err >= 0 && pcm->playback) - err = snd_pcm_delay(pcm->playback, &pdelay); - if (err >= 0 && pcm->capture) - err = snd_pcm_delay(pcm->capture, &cdelay); - if (pdelay > cdelay) - pdelay = cdelay; - *delayp = pdelay; - return err; -} - -/** - * \brief Obtain transfer block size (aka period size) - * \param pcm ordinary PCM handle - * \param tblock Returned transfer block size in frames - * \return 0 on success otherwise a negative error code - * - * All read/write operations must use this transfer block. - */ -int sndo_pcm_transfer_block(sndo_pcm_t *pcm, snd_pcm_uframes_t *tblock) -{ - int err; - - assert(pcm); - assert(tblock); - err = sndo_pcm_check_setup(pcm); - if (err < 0) - return err; - *tblock = pcm->transfer_block; - return 0; -} - -/** - * \brief Resume from suspend, no samples are lost - * \param pcm ordinary PCM handle - * \return 0 on success otherwise a negative error code - * \retval -EAGAIN resume can't be proceed immediately (audio hardware is probably still suspended) - * \retval -ENOSYS hardware doesn't support this feature - * - * This function can be used when the stream is in the suspend state - * to do the fine resume from this state. Not all hardware supports - * this feature, when an -ENOSYS error is returned, use the snd_pcm_prepare - * function to recovery. - */ -int sndo_pcm_resume(sndo_pcm_t *pcm) -{ - return snd_pcm_resume(pcm->master); -} - -/** - * \brief Wait for a PCM to become ready - * \param pcm ordinary PCM handle - * \param timeout maximum time in milliseconds to wait - * \return a positive value on success otherwise a negative error code - * \retval 0 timeout occurred - * \retval 1 PCM stream is ready for I/O - */ -int sndo_pcm_wait(sndo_pcm_t *pcm, int timeout) -{ - struct pollfd pfd[2]; - unsigned short p_revents, c_revents; - int err; - err = snd_pcm_poll_descriptors(pcm->playback, &pfd[0], 1); - assert(err == 1); - err = snd_pcm_poll_descriptors(pcm->capture, &pfd[1], 1); - assert(err == 1); - err = poll(pfd, 2, timeout); - if (err < 0) - return -errno; - if (err == 0) - return 0; - do { - err = snd_pcm_poll_descriptors_revents(pcm->playback, &pfd[0], 1, &p_revents); - if (err < 0) - return err; - if (p_revents & (POLLERR | POLLNVAL)) - return -EIO; - err = snd_pcm_poll_descriptors_revents(pcm->capture, &pfd[1], 1, &c_revents); - if (err < 0) - return err; - if (c_revents & (POLLERR | POLLNVAL)) - return -EIO; - if ((p_revents & POLLOUT) && (c_revents & POLLIN)) - return 1; - err = poll(&pfd[(p_revents & POLLOUT) ? 1 : 0], 1, 1); - if (err < 0) - return err; - } while (1); -} - -/** - * \brief Get raw (lowlevel) playback PCM handle - * \param pcm ordinary PCM handle - * \return raw (lowlevel) capture PCM handle or NULL - */ -snd_pcm_t *sndo_pcm_raw_playback(sndo_pcm_t *pcm) -{ - return pcm->playback; -} - -/** - * \brief Get raw (lowlevel) capture PCM handle - * \param pcm ordinary PCM handle - * \return raw (lowlevel) capture PCM handle or NULL - */ -snd_pcm_t *sndo_pcm_raw_capture(sndo_pcm_t *pcm) -{ - return pcm->capture; -} - -/** - * \brief Reset all parameters - * \param pcm ordinary PCM handle - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_param_reset(sndo_pcm_t *pcm) -{ - int err; - - err = sndo_pcm_drain(pcm); - if (err < 0) - return err; - pcm->initialized = 0; - if (pcm->playback) { - err = snd_pcm_hw_params_any(pcm->playback, pcm->p_hw_params); - if (err < 0) - return err; - err = snd_pcm_sw_params_current(pcm->playback, pcm->p_sw_params); - if (err < 0) - return err; - } - if (pcm->capture) { - err = snd_pcm_hw_params_any(pcm->capture, pcm->c_hw_params); - if (err < 0) - return err; - err = snd_pcm_sw_params_current(pcm->capture, pcm->c_sw_params); - if (err < 0) - return err; - } - return 0; -} - -/** - * \brief Set sample access type - * \param pcm ordinary PCM handle - * \param access access type (interleaved or noninterleaved) - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_param_access(sndo_pcm_t *pcm, enum sndo_pcm_access_type access) -{ - int err; - snd_pcm_access_t native_access = SND_PCM_ACCESS_MMAP_INTERLEAVED; - - switch (access) { - case SNDO_PCM_ACCESS_INTERLEAVED: native_access = SND_PCM_ACCESS_MMAP_INTERLEAVED; break; - case SNDO_PCM_ACCESS_NONINTERLEAVED: native_access = SND_PCM_ACCESS_MMAP_NONINTERLEAVED; break; - default: - return -EINVAL; - } - err = sndo_pcm_setup(pcm); - if (err < 0) - return err; - if (pcm->playback) { - err = snd_pcm_hw_params_set_access(pcm->playback, pcm->p_hw_params, native_access); - if (err < 0) { - SNDERR("cannot set requested access for the playback direction"); - return err; - } - } - if (pcm->capture) { - err = snd_pcm_hw_params_set_access(pcm->capture, pcm->c_hw_params, native_access); - if (err < 0) { - SNDERR("cannot set requested access for the capture direction"); - return err; - } - } - return 0; -} - -/** - * \brief Set stream rate - * \param pcm ordinary PCM handle - * \param rate requested rate - * \param used_rate returned real rate - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_param_rate(sndo_pcm_t *pcm, unsigned int rate, unsigned int *used_rate) -{ - int err; - unsigned int prate = rate, crate = rate; - - err = sndo_pcm_setup(pcm); - if (err < 0) - return err; - if (pcm->playback) { - err = snd_pcm_hw_params_set_rate_near(pcm->playback, pcm->p_hw_params, &prate, 0); - if (err < 0) { - SNDERR("cannot set requested rate for the playback direction"); - return err; - } - } - if (pcm->capture) { - err = snd_pcm_hw_params_set_rate_near(pcm->capture, pcm->c_hw_params, &crate, 0); - if (err < 0) { - SNDERR("cannot set requested rate for the capture direction"); - return err; - } - } - if (used_rate) - *used_rate = pcm->capture ? crate : prate; - return 0; -} - -/** - * \brief Set channels in stream - * \param pcm ordinary PCM handle - * \param channels requested channels - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_param_channels(sndo_pcm_t *pcm, unsigned int channels) -{ - int err; - - err = sndo_pcm_setup(pcm); - if (err < 0) - return err; - if (pcm->playback) { - err = snd_pcm_hw_params_set_channels(pcm->capture, pcm->p_hw_params, channels); - if (err < 0) { - SNDERR("cannot set requested channels for the playback direction"); - return err; - } - } - if (pcm->capture) { - err = snd_pcm_hw_params_set_channels(pcm->capture, pcm->c_hw_params, channels); - if (err < 0) { - SNDERR("cannot set requested channels for the capture direction"); - return err; - } - } - return 0; -} - -/** - * \brief Set stream format - * \param pcm ordinary PCM handle - * \param rate requested channels - * \param used_rate returned real channels - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_param_format(sndo_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_subformat_t subformat) -{ - int err; - - if (subformat != SND_PCM_SUBFORMAT_STD) - return -EINVAL; - err = snd_pcm_format_physical_width(format); - if (err < 0) - return err; - if (err % 8) - return -EINVAL; - err = sndo_pcm_setup(pcm); - if (err < 0) - return err; - if (pcm->playback) { - err = snd_pcm_hw_params_set_format(pcm->capture, pcm->p_hw_params, format); - if (err < 0) { - SNDERR("cannot set requested format for the playback direction"); - return err; - } - } - if (pcm->capture) { - err = snd_pcm_hw_params_set_format(pcm->capture, pcm->c_hw_params, format); - if (err < 0) { - SNDERR("cannot set requested format for the capture direction"); - return err; - } - } - return 0; -} - -/** - * \brief Set stream latency - * \param pcm ordinary PCM handle - * \param latency requested latency - * \param used_latency returned real latency in frames - * \return 0 on success otherwise a negative error code - * - * Note that the result value is only approximate and for one direction. - * For example, hardware FIFOs are not counted etc. - */ -int sndo_pcm_param_latency(sndo_pcm_t *pcm, enum sndo_pcm_latency_type latency, snd_pcm_uframes_t *used_latency) -{ - int err; - - err = sndo_pcm_setup(pcm); - if (err < 0) - return err; - pcm->latency = latency; - err = sndo_pcm_check_setup(pcm); - if (err < 0) - return err; - if (used_latency) - *used_latency = pcm->ring_size; - return 0; -} - -/** - * \brief Set xrun behaviour - * \param pcm ordinary PCM handle - * \param xrun requested behaviour - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_param_xrun(sndo_pcm_t *pcm, enum sndo_pcm_xrun_type xrun) -{ - int err; - - err = sndo_pcm_setup(pcm); - if (err < 0) - return err; - pcm->xrun = xrun; - return 0; -} - -/** - * \brief Begin the playback interleaved frame update - * \param pcm ordinary PCM handle - * \param ring_buffer returned pointer to actual destination area - * \param frames returned maximum count of updated frames - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_pio_ibegin(sndo_pcm_t *pcm, void **ring_buffer, snd_pcm_uframes_t *frames) -{ - int err; - const snd_pcm_channel_area_t *areas; - - err = sndo_pcm_check_setup(pcm); - if (err < 0) - return err; - err = snd_pcm_mmap_begin(pcm->playback, &areas, &pcm->p_offset, frames); - if (err < 0) - return err; - if (*frames < pcm->transfer_block) { - frames = 0; - } else { - *frames -= *frames % pcm->transfer_block; - *ring_buffer = (char *)areas->addr + (areas->first / 8) + pcm->p_offset * pcm->samplebytes; - } - return 0; -} - -/** - * \brief Finish the playback interleave frame update (commit data to hardware) - * \param pcm ordinary PCM handle - * \param frames count of updated frames - * \return count of transferred frames on success otherwise a negative error code - */ -snd_pcm_sframes_t sndo_pcm_pio_iend(sndo_pcm_t *pcm, snd_pcm_uframes_t frames) -{ - if (frames <= 0) - return -EINVAL; - if (frames % pcm->transfer_block) - return -EINVAL; - return snd_pcm_mmap_commit(pcm->playback, pcm->p_offset, frames); -} - -/** - * \brief Begin the playback noninterleaved frame update - * \param pcm ordinary PCM handle - * \param ring_buffer returned pointer to actual destination area - * \param frames returned maximum count of updated frames - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_pio_nbegin(sndo_pcm_t *pcm, void ***ring_buffer, snd_pcm_uframes_t *frames) -{ - int err; - unsigned ch; - const snd_pcm_channel_area_t *areas; - - err = sndo_pcm_check_setup(pcm); - if (err < 0) - return err; - err = snd_pcm_mmap_begin(pcm->playback, &areas, &pcm->p_offset, frames); - if (err < 0) - return err; - if (*frames < pcm->transfer_block) { - frames = 0; - } else { - *frames -= *frames % pcm->transfer_block; - for (ch = 0; ch < pcm->channels; ch++) - ring_buffer[ch] = areas->addr + (areas->first / 8) + pcm->p_offset * pcm->samplebytes; - } - return 0; -} - -/** - * \brief Finish the playback noninterleave frame update (commit data to hardware) - * \param pcm ordinary PCM handle - * \param frames count of updated frames - * \return count of transferred frames on success otherwise a negative error code - */ -snd_pcm_sframes_t sndo_pcm_pio_nend(sndo_pcm_t *pcm, snd_pcm_uframes_t frames) -{ - if (frames <= 0) - return -EINVAL; - if (frames % pcm->transfer_block) - return -EINVAL; - return snd_pcm_mmap_commit(pcm->playback, pcm->p_offset, frames); -} - -/** - * \brief Begin the capture interleaved frame update - * \param pcm ordinary PCM handle - * \param ring_buffer returned pointer to actual destination area - * \param frames returned maximum count of updated frames - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_cio_ibegin(sndo_pcm_t *pcm, void **ring_buffer, snd_pcm_uframes_t *frames) -{ - int err; - const snd_pcm_channel_area_t *areas; - - err = sndo_pcm_check_setup(pcm); - if (err < 0) - return err; - err = snd_pcm_mmap_begin(pcm->capture, &areas, &pcm->c_offset, frames); - if (err < 0) - return err; - if (*frames < pcm->transfer_block) { - frames = 0; - } else { - *frames -= *frames % pcm->transfer_block; - *ring_buffer = (char *)areas->addr + (areas->first / 8) + pcm->c_offset * pcm->samplebytes; - } - return 0; -} - -/** - * \brief Finish the capture interleave frame update (commit data to hardware) - * \param pcm ordinary PCM handle - * \param frames count of updated frames - * \return count of transferred frames on success otherwise a negative error code - */ -snd_pcm_sframes_t sndo_pcm_cio_iend(sndo_pcm_t *pcm, snd_pcm_uframes_t frames) -{ - if (frames <= 0) - return -EINVAL; - if (frames % pcm->transfer_block) - return -EINVAL; - return snd_pcm_mmap_commit(pcm->capture, pcm->p_offset, frames); -} - -/** - * \brief Begin the capture noninterleaved frame update - * \param pcm ordinary PCM handle - * \param ring_buffer returned pointer to actual destination area - * \param frames returned maximum count of updated frames - * \return 0 on success otherwise a negative error code - */ -int sndo_pcm_cio_nbegin(sndo_pcm_t *pcm, void ***ring_buffer, snd_pcm_uframes_t *frames) -{ - int err; - unsigned ch; - const snd_pcm_channel_area_t *areas; - - err = sndo_pcm_check_setup(pcm); - if (err < 0) - return err; - err = snd_pcm_mmap_begin(pcm->capture, &areas, &pcm->c_offset, frames); - if (err < 0) - return err; - if (*frames < pcm->transfer_block) { - frames = 0; - } else { - *frames -= *frames % pcm->transfer_block; - for (ch = 0; ch < pcm->channels; ch++) - ring_buffer[ch] = areas->addr + (areas->first / 8) + pcm->c_offset * pcm->samplebytes; - } - return 0; -} - -/** - * \brief Finish the capture noninterleave frame update (commit data to hardware) - * \param pcm ordinary PCM handle - * \param frames count of updated frames - * \return count of transferred frames on success otherwise a negative error code - */ -snd_pcm_sframes_t sndo_pcm_cio_nend(sndo_pcm_t *pcm, snd_pcm_uframes_t frames) -{ - if (frames <= 0) - return -EINVAL; - if (frames % pcm->transfer_block) - return -EINVAL; - return snd_pcm_mmap_commit(pcm->capture, pcm->c_offset, frames); -} - -/* - * helpers - */ - -static int sndo_pcm_setup(sndo_pcm_t *pcm) -{ - int err; - - err = sndo_pcm_drain(pcm); - if (err < 0) - return err; - if (!pcm->setting_up) { - int err = sndo_pcm_param_reset(pcm); - if (err < 0) - return err; - pcm->setting_up = 1; - } - return 0; -} - -static int sndo_pcm_initialize(sndo_pcm_t *pcm) -{ - int err; - snd_pcm_uframes_t boundary; - snd_pcm_uframes_t p_period_size = ~0UL, c_period_size = ~0UL; - snd_pcm_uframes_t p_buffer_size = ~0UL, c_buffer_size = ~0UL; - - if (pcm->playback) { - err = snd_pcm_hw_params(pcm->playback, pcm->p_hw_params); - if (err < 0) - return err; - err = snd_pcm_hw_params_get_period_size(pcm->p_hw_params, &p_period_size, NULL); - if (err < 0) - return err; - err = snd_pcm_hw_params_get_buffer_size(pcm->p_hw_params, &p_buffer_size); - if (err < 0) - return err; - } - if (pcm->capture) { - err = snd_pcm_hw_params(pcm->capture, pcm->c_hw_params); - if (err < 0) - return err; - err = snd_pcm_hw_params_get_period_size(pcm->c_hw_params, &c_period_size, NULL); - if (err < 0) - return err; - err = snd_pcm_hw_params_get_buffer_size(pcm->c_hw_params, &c_buffer_size); - if (err < 0) - return err; - } - if (p_period_size < c_period_size) - pcm->transfer_block = p_period_size; - else - pcm->transfer_block = c_period_size; - if (p_buffer_size < c_buffer_size) - pcm->ring_size = p_buffer_size; - else - pcm->ring_size = c_buffer_size; - if (pcm->playback) { - err = snd_pcm_sw_params_get_boundary(pcm->p_sw_params, &boundary); - if (err < 0) - return err; - err = snd_pcm_sw_params_set_start_threshold(pcm->playback, pcm->p_sw_params, boundary); - if (err < 0) - return err; - err = snd_pcm_sw_params_set_stop_threshold(pcm->playback, pcm->p_sw_params, pcm->xrun == SNDO_PCM_XRUN_IGNORE ? boundary : pcm->ring_size); - if (err < 0) - return err; - err = snd_pcm_sw_params_set_xfer_align(pcm->playback, pcm->p_sw_params, 1); - if (err < 0) - return err; - err = snd_pcm_sw_params_set_avail_min(pcm->playback, pcm->p_sw_params, pcm->transfer_block); - if (err < 0) - return err; - err = snd_pcm_sw_params(pcm->playback, pcm->p_sw_params); - if (err < 0) - return err; - } - if (pcm->capture) { - err = snd_pcm_sw_params_get_boundary(pcm->c_sw_params, &boundary); - if (err < 0) - return err; - err = snd_pcm_sw_params_set_start_threshold(pcm->capture, pcm->c_sw_params, boundary); - if (err < 0) - return err; - err = snd_pcm_sw_params_set_stop_threshold(pcm->capture, pcm->c_sw_params, pcm->xrun == SNDO_PCM_XRUN_IGNORE ? boundary : pcm->ring_size); - if (err < 0) - return err; - err = snd_pcm_sw_params_set_xfer_align(pcm->capture, pcm->c_sw_params, 1); - if (err < 0) - return err; - err = snd_pcm_sw_params_set_avail_min(pcm->capture, pcm->c_sw_params, pcm->transfer_block); - if (err < 0) - return err; - err = snd_pcm_sw_params(pcm->capture, pcm->c_sw_params); - if (err < 0) - return err; - } - pcm->initialized = 1; - return 0; -} -- 2.47.1