tarina

git clone https://git.tarina.org/tarina
Log | Files | Refs | README | LICENSE

alsaloop.h (6136B)


      1 /*
      2  *  A simple PCM loopback utility
      3  *  Copyright (c) 2010 by Jaroslav Kysela <perex@perex.cz>
      4  *
      5  *   This program is free software; you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation; either version 2 of the License, or
      8  *   (at your option) any later version.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  *   GNU General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU General Public License
     16  *   along with this program; if not, write to the Free Software
     17  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
     18  *
     19  */
     20 
     21 #include "aconfig.h"
     22 #ifdef HAVE_SAMPLERATE_H
     23 #define USE_SAMPLERATE
     24 #include <samplerate.h>
     25 #else
     26 enum {
     27 	SRC_SINC_BEST_QUALITY	= 0,
     28 	SRC_SINC_MEDIUM_QUALITY	= 1,
     29 	SRC_SINC_FASTEST	= 2,
     30 	SRC_ZERO_ORDER_HOLD	= 3,
     31 	SRC_LINEAR		= 4
     32 };
     33 #endif
     34 
     35 #define MAX_ARGS	128
     36 #define MAX_MIXERS	64
     37 
     38 #if 0
     39 #define FILE_PWRITE "/tmp/alsaloop.praw"
     40 #define FILE_CWRITE "/tmp/alsaloop.craw"
     41 #endif
     42 
     43 #define WORKAROUND_SERIALOPEN	(1<<0)
     44 
     45 typedef enum _sync_type {
     46 	SYNC_TYPE_NONE = 0,
     47 	SYNC_TYPE_SIMPLE,	/* add or remove samples */
     48 	SYNC_TYPE_CAPTRATESHIFT,
     49 	SYNC_TYPE_PLAYRATESHIFT,
     50 	SYNC_TYPE_SAMPLERATE,
     51 	SYNC_TYPE_AUTO,		/* order: CAPTRATESHIFT, PLAYRATESHIFT, */
     52 				/*        SAMPLERATE, SIMPLE */
     53 	SYNC_TYPE_LAST = SYNC_TYPE_AUTO
     54 } sync_type_t;
     55 
     56 typedef enum _slave_type {
     57 	SLAVE_TYPE_AUTO = 0,
     58 	SLAVE_TYPE_ON = 1,
     59 	SLAVE_TYPE_OFF = 2,
     60 	SLAVE_TYPE_LAST = SLAVE_TYPE_OFF
     61 } slave_type_t;
     62 
     63 struct loopback_control {
     64 	snd_ctl_elem_id_t *id;
     65 	snd_ctl_elem_info_t *info;
     66 	snd_ctl_elem_value_t *value;
     67 };
     68 
     69 struct loopback_mixer {
     70 	unsigned int skip:1;
     71 	struct loopback_control src;
     72 	struct loopback_control dst;
     73 	struct loopback_mixer *next;
     74 };
     75 
     76 struct loopback_ossmixer {
     77 	unsigned int skip:1;
     78 	const char *alsa_id;
     79 	int alsa_index;
     80 	const char *oss_id;
     81 	struct loopback_ossmixer *next;
     82 };
     83 
     84 struct loopback_handle {
     85 	struct loopback *loopback;
     86 	char *device;
     87 	char *ctldev;
     88 	char *id;
     89 	int card_number;
     90 	snd_pcm_t *handle;
     91 	snd_pcm_access_t access;
     92 	snd_pcm_format_t format;
     93 	unsigned int rate;
     94 	unsigned int rate_req;
     95 	unsigned int channels;
     96 	unsigned int buffer_size;
     97 	unsigned int period_size;
     98 	snd_pcm_uframes_t avail_min;
     99 	unsigned int buffer_size_req;
    100 	unsigned int period_size_req;
    101 	unsigned int frame_size;
    102 	unsigned int resample:1;	/* do resample */
    103 	unsigned int nblock:1;		/* do block (period size) transfers */
    104 	unsigned int xrun_pending:1;
    105 	unsigned int pollfd_count;
    106 	/* I/O job */
    107 	char *buf;			/* I/O buffer */
    108 	snd_pcm_uframes_t buf_pos;	/* I/O position */
    109 	snd_pcm_uframes_t buf_count;	/* filled samples */
    110 	snd_pcm_uframes_t buf_size;	/* buffer size in frames */
    111 	snd_pcm_uframes_t buf_over;	/* capture buffer overflow */
    112 	int stall;
    113 	/* statistics */
    114 	snd_pcm_uframes_t max;
    115 	unsigned long long counter;
    116 	unsigned long sync_point;	/* in samples */
    117 	snd_pcm_sframes_t last_delay;
    118 	double pitch;
    119 	snd_pcm_uframes_t total_queued;
    120 	/* control */
    121 	snd_ctl_t *ctl;
    122 	unsigned int ctl_pollfd_count;
    123 	snd_ctl_elem_value_t *ctl_notify;
    124 	snd_ctl_elem_value_t *ctl_rate_shift;
    125 	snd_ctl_elem_value_t *ctl_active;
    126 	snd_ctl_elem_value_t *ctl_format;
    127 	snd_ctl_elem_value_t *ctl_rate;
    128 	snd_ctl_elem_value_t *ctl_channels;
    129 };
    130 
    131 struct loopback {
    132 	char *id;
    133 	struct loopback_handle *capt;
    134 	struct loopback_handle *play;
    135 	snd_pcm_uframes_t latency;	/* final latency in frames */
    136 	unsigned int latency_req;	/* in frames */
    137 	unsigned int latency_reqtime;	/* in us */
    138 	unsigned long loop_time;	/* ~0 = unlimited (in seconds) */
    139 	unsigned long long loop_limit;	/* ~0 = unlimited (in frames) */
    140 	snd_output_t *output;
    141 	snd_output_t *state;
    142 	int pollfd_count;
    143 	int active_pollfd_count;
    144 	unsigned int linked:1;		/* linked streams */
    145 	unsigned int reinit:1;
    146 	unsigned int running:1;
    147 	unsigned int stop_pending:1;
    148 	snd_pcm_uframes_t stop_count;
    149 	sync_type_t sync;		/* type of sync */
    150 	slave_type_t slave;
    151 	int thread;			/* thread number */
    152 	unsigned int wake;
    153 	/* statistics */
    154 	double pitch;
    155 	double pitch_delta;
    156 	snd_pcm_sframes_t pitch_diff;
    157 	snd_pcm_sframes_t pitch_diff_min;
    158 	snd_pcm_sframes_t pitch_diff_max;
    159 	unsigned int total_queued_count;
    160 	snd_timestamp_t tstamp_start;
    161 	snd_timestamp_t tstamp_end;
    162 	/* xrun profiling */
    163 	unsigned int xrun:1;		/* xrun profiling */
    164 	snd_timestamp_t xrun_last_update;
    165 	snd_timestamp_t xrun_last_wake0;
    166 	snd_timestamp_t xrun_last_wake;
    167 	snd_timestamp_t xrun_last_check0;
    168 	snd_timestamp_t xrun_last_check;
    169 	snd_pcm_sframes_t xrun_last_pdelay;
    170 	snd_pcm_sframes_t xrun_last_cdelay;
    171 	snd_pcm_uframes_t xrun_buf_pcount;
    172 	snd_pcm_uframes_t xrun_buf_ccount;
    173 	unsigned int xrun_out_frames;
    174 	long xrun_max_proctime;
    175 	double xrun_max_missing;
    176 	/* control mixer */
    177 	struct loopback_mixer *controls;
    178 	struct loopback_ossmixer *oss_controls;
    179 	/* sample rate */
    180 	unsigned int use_samplerate:1;
    181 #ifdef USE_SAMPLERATE
    182 	unsigned int src_enable:1;
    183 	int src_converter_type;
    184 	SRC_STATE *src_state;
    185 	SRC_DATA src_data;
    186 	unsigned int src_out_frames;
    187 #endif
    188 #ifdef FILE_CWRITE
    189 	FILE *cfile;
    190 #endif
    191 #ifdef FILE_PWRITE
    192 	FILE *pfile;
    193 #endif
    194 };
    195 
    196 extern int verbose;
    197 extern int workarounds;
    198 extern int use_syslog;
    199 
    200 #define logit(priority, fmt, args...) do {		\
    201 	if (use_syslog)					\
    202 		syslog(priority, fmt, ##args);		\
    203 	else						\
    204 		fprintf(stderr, fmt, ##args);		\
    205 } while (0)
    206 
    207 int pcmjob_init(struct loopback *loop);
    208 int pcmjob_done(struct loopback *loop);
    209 int pcmjob_start(struct loopback *loop);
    210 int pcmjob_stop(struct loopback *loop);
    211 int pcmjob_pollfds_init(struct loopback *loop, struct pollfd *fds);
    212 int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds);
    213 void pcmjob_state(struct loopback *loop);
    214 
    215 int control_parse_id(const char *str, snd_ctl_elem_id_t *id);
    216 int control_id_match(snd_ctl_elem_id_t *id1, snd_ctl_elem_id_t *id2);
    217 int control_init(struct loopback *loop);
    218 int control_done(struct loopback *loop);
    219 int control_event(struct loopback_handle *lhandle, snd_ctl_event_t *ev);