tarina

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

alsaloop.c (23725B)


      1 /*
      2  *  A simple PCM loopback utility with adaptive sample rate support
      3  *
      4  *     Author: Jaroslav Kysela <perex@perex.cz>
      5  *
      6  *
      7  *   This program is free software; you can redistribute it and/or modify
      8  *   it under the terms of the GNU General Public License as published by
      9  *   the Free Software Foundation; either version 2 of the License, or
     10  *   (at your option) any later version.
     11  *
     12  *   This program is distributed in the hope that it will be useful,
     13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  *   GNU General Public License for more details.
     16  *
     17  *   You should have received a copy of the GNU General Public License
     18  *   along with this program; if not, write to the Free Software
     19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
     20  *
     21  */
     22 
     23 #include <stdio.h>
     24 #include <stdlib.h>
     25 #include <string.h>
     26 #include <sched.h>
     27 #include <errno.h>
     28 #include <getopt.h>
     29 #include <alsa/asoundlib.h>
     30 #include <sys/time.h>
     31 #include <math.h>
     32 #include <pthread.h>
     33 #include <syslog.h>
     34 #include <signal.h>
     35 #include "alsaloop.h"
     36 
     37 struct loopback_thread {
     38 	int threaded;
     39 	pthread_t thread;
     40 	int exitcode;
     41 	struct loopback **loopbacks;
     42 	int loopbacks_count;
     43 	snd_output_t *output;
     44 };
     45 
     46 int quit = 0;
     47 int verbose = 0;
     48 int workarounds = 0;
     49 int daemonize = 0;
     50 int use_syslog = 0;
     51 struct loopback **loopbacks = NULL;
     52 int loopbacks_count = 0;
     53 char **my_argv = NULL;
     54 int my_argc = 0;
     55 struct loopback_thread *threads;
     56 int threads_count = 0;
     57 pthread_t main_job;
     58 int arg_default_xrun = 0;
     59 int arg_default_wake = 0;
     60 
     61 static void my_exit(struct loopback_thread *thread, int exitcode)
     62 {
     63 	int i;
     64 
     65 	for (i = 0; i < thread->loopbacks_count; i++)
     66 		pcmjob_done(thread->loopbacks[i]);
     67 	if (thread->threaded) {
     68 		thread->exitcode = exitcode;
     69 		pthread_exit(0);
     70 	}
     71 	exit(exitcode);
     72 }
     73 
     74 static int create_loopback_handle(struct loopback_handle **_handle,
     75 				  const char *device,
     76 				  const char *ctldev,
     77 				  const char *id)
     78 {
     79 	char idbuf[1024];
     80 	struct loopback_handle *handle;
     81 
     82 	handle = calloc(1, sizeof(*handle));
     83 	if (handle == NULL)
     84 		return -ENOMEM;
     85 	if (device == NULL)
     86 		device = "hw:0,0";
     87 	handle->device = strdup(device);
     88 	if (handle->device == NULL)
     89 		return -ENOMEM;
     90 	if (ctldev) {
     91 		handle->ctldev = strdup(ctldev);
     92 		if (handle->ctldev == NULL)
     93 			return -ENOMEM;
     94 	} else {
     95 		handle->ctldev = NULL;
     96 	}
     97 	snprintf(idbuf, sizeof(idbuf)-1, "%s %s", id, device);
     98 	idbuf[sizeof(idbuf)-1] = '\0';
     99 	handle->id = strdup(idbuf);
    100 	handle->access = SND_PCM_ACCESS_RW_INTERLEAVED;
    101 	handle->format = SND_PCM_FORMAT_S16_LE;
    102 	handle->rate = handle->rate_req = 48000;
    103 	handle->channels = 2;
    104 	handle->resample = 0;
    105 	*_handle = handle;
    106 	return 0;
    107 }
    108 
    109 static int create_loopback(struct loopback **_handle,
    110 			   struct loopback_handle *play,
    111 			   struct loopback_handle *capt,
    112 			   snd_output_t *output)
    113 {
    114 	struct loopback *handle;
    115 
    116 	handle = calloc(1, sizeof(*handle));
    117 	if (handle == NULL)
    118 		return -ENOMEM;
    119 	handle->play = play;
    120 	handle->capt = capt;
    121 	play->loopback = handle;
    122 	capt->loopback = handle;
    123 	handle->latency_req = 0;
    124 	handle->latency_reqtime = 10000;
    125 	handle->loop_time = ~0UL;
    126 	handle->loop_limit = ~0ULL;
    127 	handle->output = output;
    128 	handle->state = output;
    129 #ifdef USE_SAMPLERATE
    130 	handle->src_enable = 1;
    131 	handle->src_converter_type = SRC_SINC_BEST_QUALITY;
    132 #endif
    133 	*_handle = handle;
    134 	return 0;
    135 }
    136 
    137 static void set_loop_time(struct loopback *loop, unsigned long loop_time)
    138 {
    139 	loop->loop_time = loop_time;
    140 	loop->loop_limit = loop->capt->rate * loop_time;
    141 }
    142 
    143 static void setscheduler(void)
    144 {
    145 	struct sched_param sched_param;
    146 
    147 	if (sched_getparam(0, &sched_param) < 0) {
    148 		logit(LOG_WARNING, "Scheduler getparam failed.\n");
    149 		return;
    150 	}
    151 	sched_param.sched_priority = sched_get_priority_max(SCHED_RR);
    152 	if (!sched_setscheduler(0, SCHED_RR, &sched_param)) {
    153 		if (verbose)
    154 			logit(LOG_WARNING, "Scheduler set to Round Robin with priority %i\n", sched_param.sched_priority);
    155 		return;
    156 	}
    157 	if (verbose)
    158 		logit(LOG_INFO, "!!!Scheduler set to Round Robin with priority %i FAILED!\n", sched_param.sched_priority);
    159 }
    160 
    161 void help(void)
    162 {
    163 	int k;
    164 	printf(
    165 "Usage: alsaloop [OPTION]...\n\n"
    166 "-h,--help      help\n"
    167 "-g,--config    configuration file (one line = one job specified)\n"
    168 "-d,--daemonize daemonize the main process and use syslog for errors\n"
    169 "-P,--pdevice   playback device\n"
    170 "-C,--cdevice   capture device\n"
    171 "-X,--pctl      playback ctl device\n"
    172 "-Y,--cctl      capture ctl device\n"
    173 "-l,--latency   requested latency in frames\n"
    174 "-t,--tlatency  requested latency in usec (1/1000000sec)\n"
    175 "-f,--format    sample format\n"
    176 "-c,--channels  channels\n"
    177 "-r,--rate      rate\n"
    178 "-n,--resample  resample in alsa-lib\n"
    179 "-A,--samplerate use converter (0=sincbest,1=sincmedium,2=sincfastest,\n"
    180 "                               3=zerohold,4=linear)\n"
    181 "-B,--buffer    buffer size in frames\n"
    182 "-E,--period    period size in frames\n"
    183 "-s,--seconds   duration of loop in seconds\n"
    184 "-b,--nblock    non-block mode (very early process wakeup)\n"
    185 "-S,--sync      sync mode(0=none,1=simple,2=captshift,3=playshift,4=samplerate,\n"
    186 "                         5=auto)\n"
    187 "-a,--slave     stream parameters slave mode (0=auto, 1=on, 2=off)\n"
    188 "-T,--thread    thread number (-1 = create unique)\n"
    189 "-m,--mixer	redirect mixer, argument is:\n"
    190 "		    SRC_SLAVE_ID(PLAYBACK)[@DST_SLAVE_ID(CAPTURE)]\n"
    191 "-O,--ossmixer	rescan and redirect oss mixer, argument is:\n"
    192 "		    ALSA_ID@OSS_ID  (for example: \"Master@VOLUME\")\n"
    193 "-e,--effect    apply an effect (bandpass filter sweep)\n"
    194 "-v,--verbose   verbose mode (more -v means more verbose)\n"
    195 "-w,--workaround use workaround (serialopen)\n"
    196 "-U,--xrun      xrun profiling\n"
    197 "-W,--wake      process wake timeout in ms\n"
    198 "-z,--syslog    use syslog for errors\n"
    199 );
    200 	printf("\nRecognized sample formats are:");
    201 	for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) {
    202 		const char *s = snd_pcm_format_name(k);
    203 		if (s)
    204 			printf(" %s", s);
    205 	}
    206 	printf("\n\n");
    207 	printf(
    208 "Tip #1 (usable 500ms latency, good CPU usage, superb xrun prevention):\n"
    209 "  alsaloop -t 500000\n"
    210 "Tip #2 (superb 1ms latency, but heavy CPU usage):\n"
    211 "  alsaloop -t 1000\n"
    212 );
    213 }
    214 
    215 static long timediff(struct timeval t1, struct timeval t2)
    216 {
    217 	signed long l;
    218 
    219 	t1.tv_sec -= t2.tv_sec;
    220 	l = (signed long) t1.tv_usec - (signed long) t2.tv_usec;
    221 	if (l < 0) {
    222 		t1.tv_sec--;
    223 		l = 1000000 + l;
    224 		l %= 1000000;
    225 	}
    226 	return (t1.tv_sec * 1000000) + l;
    227 }
    228 
    229 static void add_loop(struct loopback *loop)
    230 {
    231 	loopbacks = realloc(loopbacks, (loopbacks_count + 1) *
    232 						sizeof(struct loopback *));
    233 	if (loopbacks == NULL) {
    234 		logit(LOG_CRIT, "No enough memory\n");
    235 		exit(EXIT_FAILURE);
    236 	}
    237 	loopbacks[loopbacks_count++] = loop;
    238 }
    239 
    240 static int init_mixer_control(struct loopback_control *control,
    241 			      char *id)
    242 {
    243 	int err;
    244 
    245 	err = snd_ctl_elem_id_malloc(&control->id);
    246 	if (err < 0)
    247 		return err;
    248 	err = snd_ctl_elem_info_malloc(&control->info);
    249 	if (err < 0)
    250 		return err;
    251 	err = snd_ctl_elem_value_malloc(&control->value);
    252 	if (err < 0)
    253 		return err;
    254 	err = control_parse_id(id, control->id);
    255 	if (err < 0)
    256 		return err;
    257 	return 0;
    258 }
    259 
    260 static int add_mixers(struct loopback *loop,
    261 		      char **mixers,
    262 		      int mixers_count)
    263 {
    264 	struct loopback_mixer *mixer, *last = NULL;
    265 	char *str1;
    266 	int err;
    267 
    268 	while (mixers_count > 0) {
    269 		mixer = calloc(1, sizeof(*mixer));
    270 		if (mixer == NULL)
    271 			return -ENOMEM;
    272 		if (last)
    273 			last->next = mixer;
    274 		else
    275 			loop->controls = mixer;
    276 		last = mixer;
    277 		str1 = strchr(*mixers, '@');
    278 		if (str1)
    279 			*str1 = '\0';
    280 		err = init_mixer_control(&mixer->src, *mixers);
    281 		if (err < 0) {
    282 			logit(LOG_CRIT, "Wrong mixer control ID syntax '%s'\n", *mixers);
    283 			return -EINVAL;
    284 		}
    285 		err = init_mixer_control(&mixer->dst, str1 ? str1 + 1 : *mixers);
    286 		if (err < 0) {
    287 			logit(LOG_CRIT, "Wrong mixer control ID syntax '%s'\n", str1 ? str1 + 1 : *mixers);
    288 			return -EINVAL;
    289 		}
    290 		if (str1)
    291 			*str1 = '@';
    292 		mixers++;
    293 		mixers_count--;
    294 	}
    295 	return 0;
    296 }
    297 
    298 static int add_oss_mixers(struct loopback *loop,
    299 			  char **mixers,
    300 			  int mixers_count)
    301 {
    302 	struct loopback_ossmixer *mixer, *last = NULL;
    303 	char *str1, *str2;
    304 
    305 	while (mixers_count > 0) {
    306 		mixer = calloc(1, sizeof(*mixer));
    307 		if (mixer == NULL)
    308 			return -ENOMEM;
    309 		if (last)
    310 			last->next = mixer;
    311 		else
    312 			loop->oss_controls = mixer;
    313 		last = mixer;
    314 		str1 = strchr(*mixers, ',');
    315 		if (str1)
    316 			*str1 = '\0';
    317 		str2 = strchr(str1 ? str1 + 1 : *mixers, '@');
    318 		if (str2)
    319 			*str2 = '\0';
    320 		mixer->alsa_id = strdup(*mixers);
    321 		if (str1)
    322 			mixer->alsa_index = atoi(str1);
    323 		mixer->oss_id = strdup(str2 ? str2 + 1 : *mixers);
    324 		if (mixer->alsa_id == NULL || mixer->oss_id == NULL) {
    325 			logit(LOG_CRIT, "Not enough memory");
    326 			return -ENOMEM;
    327 		}
    328 		if (str1)
    329 			*str1 = ',';
    330 		if (str2)
    331 			*str2 = ',';
    332 		mixers++;
    333 		mixers_count--;
    334 	}
    335 	return 0;
    336 }
    337 
    338 static void enable_syslog(void)
    339 {
    340 	if (!use_syslog) {
    341 		use_syslog = 1;
    342 		openlog("alsaloop", LOG_NDELAY|LOG_PID, LOG_DAEMON);
    343 	}
    344 }
    345 
    346 static int parse_config_file(const char *file, snd_output_t *output);
    347 
    348 static int parse_config(int argc, char *argv[], snd_output_t *output,
    349 			int cmdline)
    350 {
    351 	struct option long_option[] =
    352 	{
    353 		{"help", 0, NULL, 'h'},
    354 		{"config", 1, NULL, 'g'},
    355 		{"daemonize", 0, NULL, 'd'},
    356 		{"pdevice", 1, NULL, 'P'},
    357 		{"cdevice", 1, NULL, 'C'},
    358 		{"pctl", 1, NULL, 'X'},
    359 		{"cctl", 1, NULL, 'Y'},
    360 		{"latency", 1, NULL, 'l'},
    361 		{"tlatency", 1, NULL, 't'},
    362 		{"format", 1, NULL, 'f'},
    363 		{"channels", 1, NULL, 'c'},
    364 		{"rate", 1, NULL, 'r'},
    365 		{"buffer", 1, NULL, 'B'},
    366 		{"period", 1, NULL, 'E'},
    367 		{"seconds", 1, NULL, 's'},
    368 		{"nblock", 0, NULL, 'b'},
    369 		{"effect", 0, NULL, 'e'},
    370 		{"verbose", 0, NULL, 'v'},
    371 		{"resample", 0, NULL, 'n'},
    372 		{"samplerate", 1, NULL, 'A'},
    373 		{"sync", 1, NULL, 'S'},
    374 		{"slave", 1, NULL, 'a'},
    375 		{"thread", 1, NULL, 'T'},
    376 		{"mixer", 1, NULL, 'm'},
    377 		{"ossmixer", 1, NULL, 'O'},
    378 		{"workaround", 1, NULL, 'w'},
    379 		{"xrun", 0, NULL, 'U'},
    380 		{"syslog", 0, NULL, 'z'},
    381 		{NULL, 0, NULL, 0},
    382 	};
    383 	int err, morehelp;
    384 	char *arg_config = NULL;
    385 	char *arg_pdevice = NULL;
    386 	char *arg_cdevice = NULL;
    387 	char *arg_pctl = NULL;
    388 	char *arg_cctl = NULL;
    389 	unsigned int arg_latency_req = 0;
    390 	unsigned int arg_latency_reqtime = 10000;
    391 	snd_pcm_format_t arg_format = SND_PCM_FORMAT_S16_LE;
    392 	unsigned int arg_channels = 2;
    393 	unsigned int arg_rate = 48000;
    394 	snd_pcm_uframes_t arg_buffer_size = 0;
    395 	snd_pcm_uframes_t arg_period_size = 0;
    396 	unsigned long arg_loop_time = ~0UL;
    397 	int arg_nblock = 0;
    398 	int arg_effect = 0;
    399 	int arg_resample = 0;
    400 #ifdef USE_SAMPLERATE
    401 	int arg_samplerate = SRC_SINC_FASTEST + 1;
    402 #endif
    403 	int arg_sync = SYNC_TYPE_AUTO;
    404 	int arg_slave = SLAVE_TYPE_AUTO;
    405 	int arg_thread = 0;
    406 	struct loopback *loop = NULL;
    407 	char *arg_mixers[MAX_MIXERS];
    408 	int arg_mixers_count = 0;
    409 	char *arg_ossmixers[MAX_MIXERS];
    410 	int arg_ossmixers_count = 0;
    411 	int arg_xrun = arg_default_xrun;
    412 	int arg_wake = arg_default_wake;
    413 
    414 	morehelp = 0;
    415 	while (1) {
    416 		int c;
    417 		if ((c = getopt_long(argc, argv,
    418 				"hdg:P:C:X:Y:l:t:F:f:c:r:s:benvA:S:a:m:T:O:w:UW:z",
    419 				long_option, NULL)) < 0)
    420 			break;
    421 		switch (c) {
    422 		case 'h':
    423 			morehelp++;
    424 			break;
    425 		case 'g':
    426 			arg_config = strdup(optarg);
    427 			break;
    428 		case 'd':
    429 			daemonize = 1;
    430 			enable_syslog();
    431 			break;
    432 		case 'P':
    433 			arg_pdevice = strdup(optarg);
    434 			break;
    435 		case 'C':
    436 			arg_cdevice = strdup(optarg);
    437 			break;
    438 		case 'X':
    439 			arg_pctl = strdup(optarg);
    440 			break;
    441 		case 'Y':
    442 			arg_cctl = strdup(optarg);
    443 			break;
    444 		case 'l':
    445 			err = atoi(optarg);
    446 			arg_latency_req = err >= 4 ? err : 4;
    447 			break;
    448 		case 't':
    449 			err = atoi(optarg);
    450 			arg_latency_reqtime = err >= 500 ? err : 500;
    451 			break;
    452 		case 'f':
    453 			arg_format = snd_pcm_format_value(optarg);
    454 			if (arg_format == SND_PCM_FORMAT_UNKNOWN) {
    455 				logit(LOG_WARNING, "Unknown format, setting to default S16_LE\n");
    456 				arg_format = SND_PCM_FORMAT_S16_LE;
    457 			}
    458 			break;
    459 		case 'c':
    460 			err = atoi(optarg);
    461 			arg_channels = err >= 1 && err < 1024 ? err : 1;
    462 			break;
    463 		case 'r':
    464 			err = atoi(optarg);
    465 			arg_rate = err >= 4000 && err < 200000 ? err : 44100;
    466 			break;
    467 		case 'B':
    468 			err = atoi(optarg);
    469 			arg_buffer_size = err >= 32 && err < 200000 ? err : 0;
    470 			break;
    471 		case 'E':
    472 			err = atoi(optarg);
    473 			arg_period_size = err >= 32 && err < 200000 ? err : 0;
    474 			break;
    475 		case 's':
    476 			err = atoi(optarg);
    477 			arg_loop_time = err >= 1 && err <= 100000 ? err : 30;
    478 			break;
    479 		case 'b':
    480 			arg_nblock = 1;
    481 			break;
    482 		case 'e':
    483 			arg_effect = 1;
    484 			break;
    485 		case 'n':
    486 			arg_resample = 1;
    487 			break;
    488 #ifdef USE_SAMPLERATE
    489 		case 'A':
    490 			if (strcasecmp(optarg, "sincbest") == 0)
    491 				arg_samplerate = SRC_SINC_BEST_QUALITY;
    492 			else if (strcasecmp(optarg, "sincmedium") == 0)
    493 				arg_samplerate = SRC_SINC_MEDIUM_QUALITY;
    494 			else if (strcasecmp(optarg, "sincfastest") == 0)
    495 				arg_samplerate = SRC_SINC_FASTEST;
    496 			else if (strcasecmp(optarg, "zerohold") == 0)
    497 				arg_samplerate = SRC_ZERO_ORDER_HOLD;
    498 			else if (strcasecmp(optarg, "linear") == 0)
    499 				arg_samplerate = SRC_LINEAR;
    500 			else
    501 				arg_samplerate = atoi(optarg);
    502 			if (arg_samplerate < 0 || arg_samplerate > SRC_LINEAR)
    503 				arg_sync = SRC_SINC_FASTEST;
    504 			arg_samplerate += 1;
    505 			break;
    506 #endif
    507 		case 'S':
    508 			if (strcasecmp(optarg, "samplerate") == 0)
    509 				arg_sync = SYNC_TYPE_SAMPLERATE;
    510 			else if (optarg[0] == 'n')
    511 				arg_sync = SYNC_TYPE_NONE;
    512 			else if (optarg[0] == 's')
    513 				arg_sync = SYNC_TYPE_SIMPLE;
    514 			else if (optarg[0] == 'c')
    515 				arg_sync = SYNC_TYPE_CAPTRATESHIFT;
    516 			else if (optarg[0] == 'p')
    517 				arg_sync = SYNC_TYPE_PLAYRATESHIFT;
    518 			else if (optarg[0] == 'r')
    519 				arg_sync = SYNC_TYPE_SAMPLERATE;
    520 			else
    521 				arg_sync = atoi(optarg);
    522 			if (arg_sync < 0 || arg_sync > SYNC_TYPE_LAST)
    523 				arg_sync = SYNC_TYPE_AUTO;
    524 			break;
    525 		case 'a':
    526 			if (optarg[0] == 'a')
    527 				arg_slave = SLAVE_TYPE_AUTO;
    528 			else if (strcasecmp(optarg, "on") == 0)
    529 				arg_slave = SLAVE_TYPE_ON;
    530 			else if (strcasecmp(optarg, "off") == 0)
    531 				arg_slave = SLAVE_TYPE_OFF;
    532 			else
    533 				arg_slave = atoi(optarg);
    534 			if (arg_slave < 0 || arg_slave > SLAVE_TYPE_LAST)
    535 				arg_slave = SLAVE_TYPE_AUTO;
    536 			break;
    537 		case 'T':
    538 			arg_thread = atoi(optarg);
    539 			if (arg_thread < 0)
    540 				arg_thread = 10000000 + loopbacks_count;
    541 			break;
    542 		case 'm':
    543 			if (arg_mixers_count >= MAX_MIXERS) {
    544 				logit(LOG_CRIT, "Maximum redirected mixer controls reached (max %i)\n", (int)MAX_MIXERS);
    545 				exit(EXIT_FAILURE);
    546 			}
    547 			arg_mixers[arg_mixers_count++] = optarg;
    548 			break;
    549 		case 'O':
    550 			if (arg_ossmixers_count >= MAX_MIXERS) {
    551 				logit(LOG_CRIT, "Maximum redirected mixer controls reached (max %i)\n", (int)MAX_MIXERS);
    552 				exit(EXIT_FAILURE);
    553 			}
    554 			arg_ossmixers[arg_ossmixers_count++] = optarg;
    555 			break;
    556 		case 'v':
    557 			verbose++;
    558 			break;
    559 		case 'w':
    560 			if (strcasecmp(optarg, "serialopen") == 0)
    561 				workarounds |= WORKAROUND_SERIALOPEN;
    562 			break;
    563 		case 'U':
    564 			arg_xrun = 1;
    565 			if (cmdline)
    566 				arg_default_xrun = 1;
    567 			break;
    568 		case 'W':
    569 			arg_wake = atoi(optarg);
    570 			if (cmdline)
    571 				arg_default_wake = arg_wake;
    572 			break;
    573 		case 'z':
    574 			enable_syslog();
    575 			break;
    576 		}
    577 	}
    578 
    579 	if (morehelp) {
    580 		help();
    581 		exit(EXIT_SUCCESS);
    582 	}
    583 	if (arg_config == NULL) {
    584 		struct loopback_handle *play;
    585 		struct loopback_handle *capt;
    586 		err = create_loopback_handle(&play, arg_pdevice, arg_pctl, "playback");
    587 		if (err < 0) {
    588 			logit(LOG_CRIT, "Unable to create playback handle.\n");
    589 			exit(EXIT_FAILURE);
    590 		}
    591 		err = create_loopback_handle(&capt, arg_cdevice, arg_cctl, "capture");
    592 		if (err < 0) {
    593 			logit(LOG_CRIT, "Unable to create capture handle.\n");
    594 			exit(EXIT_FAILURE);
    595 		}
    596 		err = create_loopback(&loop, play, capt, output);
    597 		if (err < 0) {
    598 			logit(LOG_CRIT, "Unable to create loopback handle.\n");
    599 			exit(EXIT_FAILURE);
    600 		}
    601 		play->format = capt->format = arg_format;
    602 		play->rate = play->rate_req = capt->rate = capt->rate_req = arg_rate;
    603 		play->channels = capt->channels = arg_channels;
    604 		play->buffer_size_req = capt->buffer_size_req = arg_buffer_size;
    605 		play->period_size_req = capt->period_size_req = arg_period_size;
    606 		play->resample = capt->resample = arg_resample;
    607 		play->nblock = capt->nblock = arg_nblock ? 1 : 0;
    608 		loop->latency_req = arg_latency_req;
    609 		loop->latency_reqtime = arg_latency_reqtime;
    610 		loop->sync = arg_sync;
    611 		loop->slave = arg_slave;
    612 		loop->thread = arg_thread;
    613 		loop->xrun = arg_xrun;
    614 		loop->wake = arg_wake;
    615 		err = add_mixers(loop, arg_mixers, arg_mixers_count);
    616 		if (err < 0) {
    617 			logit(LOG_CRIT, "Unable to add mixer controls.\n");
    618 			exit(EXIT_FAILURE);
    619 		}
    620 		err = add_oss_mixers(loop, arg_ossmixers, arg_ossmixers_count);
    621 		if (err < 0) {
    622 			logit(LOG_CRIT, "Unable to add ossmixer controls.\n");
    623 			exit(EXIT_FAILURE);
    624 		}
    625 #ifdef USE_SAMPLERATE
    626 		loop->src_enable = arg_samplerate > 0;
    627 		if (loop->src_enable)
    628 			loop->src_converter_type = arg_samplerate - 1;
    629 #endif
    630 		set_loop_time(loop, arg_loop_time);
    631 		add_loop(loop);
    632 		return 0;
    633 	}
    634 
    635 	return parse_config_file(arg_config, output);
    636 }
    637 
    638 static int parse_config_file(const char *file, snd_output_t *output)
    639 {
    640 	FILE *fp;
    641 	char line[2048], word[2048];
    642 	char *str, *ptr;
    643 	int argc, c, err = 0;
    644 	char **argv;
    645 
    646 	fp = fopen(file, "r");
    647 	if (fp == NULL) {
    648 		logit(LOG_CRIT, "Unable to open file '%s': %s\n", file, strerror(errno));
    649 		return -EIO;
    650 	}
    651 	while (!feof(fp)) {
    652 		if (fgets(line, sizeof(line)-1, fp) == NULL)
    653 			break;
    654 		line[sizeof(line)-1] = '\0';
    655 		my_argv = realloc(my_argv, my_argc + MAX_ARGS * sizeof(char *));
    656 		if (my_argv == NULL)
    657 			return -ENOMEM;
    658 		argv = my_argv + my_argc;
    659 		argc = 0;
    660 		argv[argc++] = strdup("<prog>");
    661 		my_argc++;
    662 		str = line;
    663 		while (*str) {
    664 			ptr = word;
    665 			while (*str && (*str == ' ' || *str < ' '))
    666 				str++;
    667 			if (*str == '#')
    668 				goto __next;
    669 			if (*str == '\'' || *str == '\"') {
    670 				c = *str++;
    671 				while (*str && *str != c)
    672 					*ptr++ = *str++;
    673 				if (*str == c)
    674 					str++;
    675 			} else {
    676 				while (*str && *str != ' ' && *str != '\t')
    677 					*ptr++ = *str++;
    678 			}
    679 			if (ptr != word) {
    680 				if (*(ptr-1) == '\n')
    681 					ptr--;
    682 				*ptr = '\0';
    683 				if (argc >= MAX_ARGS) {
    684 					logit(LOG_CRIT, "Too many arguments.");
    685 					goto __error;
    686 				}
    687 				argv[argc++] = strdup(word);
    688 				my_argc++;
    689 			}
    690 		}
    691 		/* erase runtime variables for getopt */
    692 		optarg = NULL;
    693 		optind = opterr = 1;
    694 		optopt = '?';
    695 
    696 		err = parse_config(argc, argv, output, 0);
    697 	      __next:
    698 		if (err < 0)
    699 			break;
    700 		err = 0;
    701 	}
    702       __error:
    703 	fclose(fp);
    704 
    705 	return err;
    706 }
    707 
    708 static void thread_job1(void *_data)
    709 {
    710 	struct loopback_thread *thread = _data;
    711 	snd_output_t *output = thread->output;
    712 	struct pollfd *pfds = NULL;
    713 	int pfds_count = 0;
    714 	int i, j, err, wake = 1000000;
    715 
    716 	setscheduler();
    717 
    718 	for (i = 0; i < thread->loopbacks_count; i++) {
    719 		err = pcmjob_init(thread->loopbacks[i]);
    720 		if (err < 0) {
    721 			logit(LOG_CRIT, "Loopback initialization failure.\n");
    722 			my_exit(thread, EXIT_FAILURE);
    723 		}
    724 	}
    725 	for (i = 0; i < thread->loopbacks_count; i++) {
    726 		err = pcmjob_start(thread->loopbacks[i]);
    727 		if (err < 0) {
    728 			logit(LOG_CRIT, "Loopback start failure.\n");
    729 			my_exit(thread, EXIT_FAILURE);
    730 		}
    731 		pfds_count += thread->loopbacks[i]->pollfd_count;
    732 		j = thread->loopbacks[i]->wake;
    733 		if (j > 0 && j < wake)
    734 			wake = j;
    735 	}
    736 	if (wake >= 1000000)
    737 		wake = -1;
    738 	pfds = calloc(pfds_count, sizeof(struct pollfd));
    739 	if (pfds == NULL || pfds_count <= 0) {
    740 		logit(LOG_CRIT, "Poll FDs allocation failed.\n");
    741 		my_exit(thread, EXIT_FAILURE);
    742 	}
    743 	while (!quit) {
    744 		struct timeval tv1, tv2;
    745 		for (i = j = 0; i < thread->loopbacks_count; i++) {
    746 			err = pcmjob_pollfds_init(thread->loopbacks[i], &pfds[j]);
    747 			if (err < 0) {
    748 				logit(LOG_CRIT, "Poll FD initialization failed.\n");
    749 				my_exit(thread, EXIT_FAILURE);
    750 			}
    751 			j += err;
    752 		}
    753 		if (verbose > 10)
    754 			gettimeofday(&tv1, NULL);
    755 		err = poll(pfds, j, wake);
    756 		if (err < 0)
    757 			err = -errno;
    758 		if (verbose > 10) {
    759 			gettimeofday(&tv2, NULL);
    760 			snd_output_printf(output, "pool took %lius\n", timediff(tv2, tv1));
    761 		}
    762 		if (err < 0) {
    763 			if (err == -EINTR || err == -ERESTART)
    764 				continue;
    765 			logit(LOG_CRIT, "Poll failed: %s\n", strerror(-err));
    766 			my_exit(thread, EXIT_FAILURE);
    767 		}
    768 		for (i = j = 0; i < thread->loopbacks_count; i++) {
    769 			struct loopback *loop = thread->loopbacks[i];
    770 			if (j < loop->active_pollfd_count) {
    771 				err = pcmjob_pollfds_handle(loop, &pfds[j]);
    772 				if (err < 0) {
    773 					logit(LOG_CRIT, "pcmjob failed.\n");
    774 					exit(EXIT_FAILURE);
    775 				}
    776 			}
    777 			j += loop->active_pollfd_count;
    778 		}
    779 	}
    780 
    781 	my_exit(thread, EXIT_SUCCESS);
    782 }
    783 
    784 static void thread_job(struct loopback_thread *thread)
    785 {
    786 	if (!thread->threaded) {
    787 		thread_job1(thread);
    788 		return;
    789 	}
    790 	pthread_create(&thread->thread, NULL, (void *) &thread_job1,
    791 					      (void *) thread);
    792 }
    793 
    794 static void send_to_all(int sig)
    795 {
    796 	struct loopback_thread *thread;
    797 	int i;
    798 
    799 	for (i = 0; i < threads_count; i++) {
    800 		thread = &threads[i];
    801 		if (thread->threaded)
    802 			pthread_kill(thread->thread, sig);
    803 	}
    804 }
    805 
    806 static void signal_handler(int sig)
    807 {
    808 	quit = 1;
    809 	send_to_all(SIGUSR2);
    810 }
    811 
    812 static void signal_handler_state(int sig)
    813 {
    814 	pthread_t self = pthread_self();
    815 	struct loopback_thread *thread;
    816 	int i, j;
    817 
    818 	if (pthread_equal(main_job, self))
    819 		send_to_all(SIGUSR1);
    820 	for (i = 0; i < threads_count; i++) {
    821 		thread = &threads[i];
    822 		if (thread->thread == self) {
    823 			for (j = 0; j < thread->loopbacks_count; j++)
    824 				pcmjob_state(thread->loopbacks[j]);
    825 		}
    826 	}
    827 	signal(sig, signal_handler_state);
    828 }
    829 
    830 static void signal_handler_ignore(int sig)
    831 {
    832 	signal(sig, signal_handler_ignore);
    833 }
    834 
    835 int main(int argc, char *argv[])
    836 {
    837 	snd_output_t *output;
    838 	int i, j, k, l, err;
    839 
    840 	err = snd_output_stdio_attach(&output, stdout, 0);
    841 	if (err < 0) {
    842 		logit(LOG_CRIT, "Output failed: %s\n", snd_strerror(err));
    843 		exit(EXIT_FAILURE);
    844 	}
    845 	err = parse_config(argc, argv, output, 1);
    846 	if (err < 0) {
    847 		logit(LOG_CRIT, "Unable to parse arguments or configuration...\n");
    848 		exit(EXIT_FAILURE);
    849 	}
    850 	while (my_argc > 0)
    851 		free(my_argv[--my_argc]);
    852 	free(my_argv);
    853 
    854 	if (loopbacks_count <= 0) {
    855 		logit(LOG_CRIT, "No loopback defined...\n");
    856 		exit(EXIT_FAILURE);
    857 	}
    858 
    859 	if (daemonize) {
    860 		if (daemon(0, 0) < 0) {
    861 			logit(LOG_CRIT, "daemon() failed: %s\n", strerror(errno));
    862 			exit(EXIT_FAILURE);
    863 		}
    864 		i = fork();
    865 		if (i < 0) {
    866 			logit(LOG_CRIT, "fork() failed: %s\n", strerror(errno));
    867 			exit(EXIT_FAILURE);
    868 		}
    869 		if (i > 0) {
    870 			/* wait(&i); */
    871 			exit(EXIT_SUCCESS);
    872 		}
    873 	}
    874 
    875 	/* we must sort thread IDs */
    876 	j = -1;
    877 	do {
    878 		k = 0x7fffffff;
    879 		for (i = 0; i < loopbacks_count; i++) {
    880 			if (loopbacks[i]->thread < k &&
    881 			    loopbacks[i]->thread > j)
    882 				k = loopbacks[i]->thread;
    883 		}
    884 		j++;
    885 		for (i = 0; i < loopbacks_count; i++) {
    886 			if (loopbacks[i]->thread == k)
    887 				loopbacks[i]->thread = j;
    888 		}
    889 	} while (k != 0x7fffffff);
    890 	/* fix maximum thread id */
    891 	for (i = 0, j = -1; i < loopbacks_count; i++) {
    892 		if (loopbacks[i]->thread > j)
    893 			j = loopbacks[i]->thread;
    894 	}
    895 	j += 1;
    896 	threads = calloc(1, sizeof(struct loopback_thread) * j);
    897 	if (threads == NULL) {
    898 		logit(LOG_CRIT, "No enough memory\n");
    899 		exit(EXIT_FAILURE);
    900 	}
    901 	/* sort all threads */
    902 	for (k = 0; k < j; k++) {
    903 		for (i = l = 0; i < loopbacks_count; i++)
    904 			if (loopbacks[i]->thread == k)
    905 				l++;
    906 		threads[k].loopbacks = malloc(l * sizeof(struct loopback *));
    907 		threads[k].loopbacks_count = l;
    908 		threads[k].output = output;
    909 		threads[k].threaded = j > 1;
    910 		for (i = l = 0; i < loopbacks_count; i++)
    911 			if (loopbacks[i]->thread == k)
    912 				threads[k].loopbacks[l++] = loopbacks[i];
    913 	}
    914 	threads_count = j;
    915 	main_job = pthread_self();
    916  
    917 	signal(SIGINT, signal_handler);
    918 	signal(SIGTERM, signal_handler);
    919 	signal(SIGABRT, signal_handler);
    920 	signal(SIGUSR1, signal_handler_state);
    921 	signal(SIGUSR2, signal_handler_ignore);
    922 
    923 	for (k = 0; k < threads_count; k++)
    924 		thread_job(&threads[k]);
    925 
    926 	if (j > 1) {
    927 		for (k = 0; k < threads_count; k++)
    928 			pthread_join(threads[k].thread, NULL);
    929 	}
    930 
    931 	if (use_syslog)
    932 		closelog();
    933 	exit(EXIT_SUCCESS);
    934 }