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);