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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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_pitch; 126 snd_ctl_elem_value_t *ctl_active; 127 snd_ctl_elem_value_t *ctl_format; 128 snd_ctl_elem_value_t *ctl_rate; 129 snd_ctl_elem_value_t *ctl_channels; 130 char *prateshift_name; /* ascii name for the playback rate shift ctl elem */ 131 }; 132 133 struct loopback { 134 char *id; 135 struct loopback_handle *capt; 136 struct loopback_handle *play; 137 snd_pcm_uframes_t latency; /* final latency in frames */ 138 unsigned int latency_req; /* in frames */ 139 unsigned int latency_reqtime; /* in us */ 140 unsigned long loop_time; /* ~0 = unlimited (in seconds) */ 141 unsigned long long loop_limit; /* ~0 = unlimited (in frames) */ 142 snd_output_t *output; 143 snd_output_t *state; 144 int pollfd_count; 145 int active_pollfd_count; 146 unsigned int linked:1; /* linked streams */ 147 unsigned int reinit:1; 148 unsigned int running:1; 149 unsigned int stop_pending:1; 150 snd_pcm_uframes_t stop_count; 151 sync_type_t sync; /* type of sync */ 152 slave_type_t slave; 153 int thread; /* thread number */ 154 unsigned int wake; 155 /* statistics */ 156 double pitch; 157 double pitch_delta; 158 snd_pcm_sframes_t pitch_diff; 159 snd_pcm_sframes_t pitch_diff_min; 160 snd_pcm_sframes_t pitch_diff_max; 161 unsigned int total_queued_count; 162 snd_timestamp_t tstamp_start; 163 snd_timestamp_t tstamp_end; 164 /* xrun profiling */ 165 unsigned int xrun:1; /* xrun profiling */ 166 snd_timestamp_t xrun_last_update; 167 snd_timestamp_t xrun_last_wake0; 168 snd_timestamp_t xrun_last_wake; 169 snd_timestamp_t xrun_last_check0; 170 snd_timestamp_t xrun_last_check; 171 snd_pcm_sframes_t xrun_last_pdelay; 172 snd_pcm_sframes_t xrun_last_cdelay; 173 snd_pcm_uframes_t xrun_buf_pcount; 174 snd_pcm_uframes_t xrun_buf_ccount; 175 unsigned int xrun_out_frames; 176 long xrun_max_proctime; 177 double xrun_max_missing; 178 /* control mixer */ 179 struct loopback_mixer *controls; 180 struct loopback_ossmixer *oss_controls; 181 /* sample rate */ 182 unsigned int use_samplerate:1; 183 #ifdef USE_SAMPLERATE 184 unsigned int src_enable:1; 185 int src_converter_type; 186 SRC_STATE *src_state; 187 SRC_DATA src_data; 188 unsigned int src_out_frames; 189 #endif 190 #ifdef FILE_CWRITE 191 FILE *cfile; 192 #endif 193 #ifdef FILE_PWRITE 194 FILE *pfile; 195 #endif 196 }; 197 198 extern int verbose; 199 extern int workarounds; 200 extern int use_syslog; 201 202 #define logit(priority, fmt, args...) do { \ 203 if (use_syslog) \ 204 syslog(priority, fmt, ##args); \ 205 else \ 206 fprintf(stderr, fmt, ##args); \ 207 } while (0) 208 209 int pcmjob_init(struct loopback *loop); 210 int pcmjob_done(struct loopback *loop); 211 int pcmjob_start(struct loopback *loop); 212 int pcmjob_stop(struct loopback *loop); 213 int pcmjob_pollfds_init(struct loopback *loop, struct pollfd *fds); 214 int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds); 215 void pcmjob_state(struct loopback *loop); 216 217 int control_parse_id(const char *str, snd_ctl_elem_id_t *id); 218 int control_id_match(snd_ctl_elem_id_t *id1, snd_ctl_elem_id_t *id2); 219 int control_init(struct loopback *loop); 220 int control_done(struct loopback *loop); 221 int control_event(struct loopback_handle *lhandle, snd_ctl_event_t *ev); 222