Ejemplo n.º 1
0
int main(int argc, char *argv[])
{
	struct option long_option[] =
	{
		{"help", 0, NULL, 'h'},
		{"pdevice", 1, NULL, 'P'},
		{"cdevice", 1, NULL, 'C'},
		{"min", 1, NULL, 'm'},
		{"max", 1, NULL, 'M'},
		{"frames", 1, NULL, 'F'},
		{"format", 1, NULL, 'f'},
		{"channels", 1, NULL, 'c'},
		{"rate", 1, NULL, 'r'},
		{"seconds", 1, NULL, 's'},
		{"block", 0, NULL, 'b'},
		{"time", 1, NULL, 't'},
		{"poll", 0, NULL, 'p'},
		{"effect", 0, NULL, 'e'},
		{NULL, 0, NULL, 0},
	};
	snd_pcm_t *phandle, *chandle;
	char *buffer;
	int err, latency, morehelp;
	int ok;
	snd_timestamp_t p_tstamp, c_tstamp;
	ssize_t r;
	size_t frames_in, frames_out, in_max;
	int effect = 0;
	morehelp = 0;
	while (1) {
		int c;
		if ((c = getopt_long(argc, argv, "hP:C:m:M:F:f:c:r:s:bt:pe", long_option, NULL)) < 0)
			break;
		switch (c) {
		case 'h':
			morehelp++;
			break;
		case 'P':
			pdevice = strdup(optarg);
			break;
		case 'C':
			cdevice = strdup(optarg);
			break;
		case 'm':
			err = atoi(optarg) / 2;
			latency_min = err >= 4 ? err : 4;
			if (latency_max < latency_min)
				latency_max = latency_min;
			break;
		case 'M':
			err = atoi(optarg) / 2;
			latency_max = latency_min > err ? latency_min : err;
			break;
		case 'f':
			format = snd_pcm_format_value(optarg);
			if (format == SND_PCM_FORMAT_UNKNOWN) {
				printf("Unknown format, setting to default S16_LE\n");
				format = SND_PCM_FORMAT_S16_LE;
			}
			break;
		case 'c':
			err = atoi(optarg);
			channels = err >= 1 && err < 1024 ? err : 1;
			break;
		case 'r':
			err = atoi(optarg);
			rate = err >= 4000 && err < 200000 ? err : 44100;
			break;
		case 's':
			err = atoi(optarg);
			loop_sec = err >= 1 && err <= 100000 ? err : 30;
			break;
		case 'b':
			block = 1;
			break;
		case 't':
			tick_time = atoi(optarg);
			tick_time = tick_time < 0 ? 0 : tick_time;
			break;
		case 'p':
			use_poll = 1;
			break;
		case 'e':
			effect = 1;
			break;
		}
	}

	if (morehelp) {
		help();
		return 0;
	}
	err = snd_output_stdio_attach(&output, stdout, 0);
	if (err < 0) {
		printf("Output failed: %s\n", snd_strerror(err));
		return 0;
	}

	loop_limit = loop_sec * rate;
	latency = latency_min - 4;
	buffer = malloc((latency_max * snd_pcm_format_width(format) / 8) * 2);

	setscheduler();

	printf("Playback device is %s\n", pdevice);
	printf("Capture device is %s\n", cdevice);
	printf("Parameters are %iHz, %s, %i channels, %s mode\n", rate, snd_pcm_format_name(format), channels, block ? "blocking" : "non-blocking");
	printf("Wanted tick time: %ius, poll mode: %s\n", tick_time, use_poll ? "yes" : "no");
	printf("Loop limit is %li frames, minimum latency = %i, maximum latency = %i\n", loop_limit, latency_min * 2, latency_max * 2);

	if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, block ? 0 : SND_PCM_NONBLOCK)) < 0) {
		printf("Playback open error: %s\n", snd_strerror(err));
		return 0;
	}
	if ((err = snd_pcm_open(&chandle, cdevice, SND_PCM_STREAM_CAPTURE, block ? 0 : SND_PCM_NONBLOCK)) < 0) {
		printf("Record open error: %s\n", snd_strerror(err));
		return 0;
	}

	/* initialize the filter sweep variables */
	if (effect) {
		fs = (float) rate;
		BW = FILTER_BANDWIDTH;

		lfo = 0;
		dlfo = 2.*M_PI*FILTERSWEEP_LFO_FREQ/fs;

		x[0] = (float*) malloc(channels*sizeof(float));		
		x[1] = (float*) malloc(channels*sizeof(float));		
		x[2] = (float*) malloc(channels*sizeof(float));		
		y[0] = (float*) malloc(channels*sizeof(float));		
		y[1] = (float*) malloc(channels*sizeof(float));		
		y[2] = (float*) malloc(channels*sizeof(float));		
	}
			  
	while (1) {
		frames_in = frames_out = 0;
		if (setparams(phandle, chandle, &latency) < 0)
			break;
		showlatency(latency);
		if (tick_time_ok)
			printf("Using tick time %ius\n", tick_time_ok);
		if ((err = snd_pcm_link(chandle, phandle)) < 0) {
			printf("Streams link error: %s\n", snd_strerror(err));
			exit(0);
		}
		if (snd_pcm_format_set_silence(format, buffer, latency*channels) < 0) {
			fprintf(stderr, "silence error\n");
			break;
		}
		if (writebuf(phandle, buffer, latency, &frames_out) < 0) {
			fprintf(stderr, "write error\n");
			break;
		}
		if (writebuf(phandle, buffer, latency, &frames_out) < 0) {
			fprintf(stderr, "write error\n");
			break;
		}

		if ((err = snd_pcm_start(chandle)) < 0) {
			printf("Go error: %s\n", snd_strerror(err));
			exit(0);
		}
		gettimestamp(phandle, &p_tstamp);
		gettimestamp(chandle, &c_tstamp);
#if 0
		printf("Playback:\n");
		showstat(phandle, frames_out);
		printf("Capture:\n");
		showstat(chandle, frames_in);
#endif

		ok = 1;
		in_max = 0;
		while (ok && frames_in < loop_limit) {
			if (use_poll) {
				/* use poll to wait for next event */
				snd_pcm_wait(chandle, 1000);
			}
			if ((r = readbuf(chandle, buffer, latency, &frames_in, &in_max)) < 0)
				ok = 0;
			else {
				if (effect)
					applyeffect(buffer,r);
			 	if (writebuf(phandle, buffer, r, &frames_out) < 0)
					ok = 0;
			}
		}
		if (ok)
			printf("Success\n");
		else
			printf("Failure\n");
		printf("Playback:\n");
		showstat(phandle, frames_out);
		printf("Capture:\n");
		showstat(chandle, frames_in);
		showinmax(in_max);
		if (p_tstamp.tv_sec == p_tstamp.tv_sec &&
		    p_tstamp.tv_usec == c_tstamp.tv_usec)
			printf("Hardware sync\n");
		snd_pcm_drop(chandle);
		snd_pcm_nonblock(phandle, 0);
		snd_pcm_drain(phandle);
		snd_pcm_nonblock(phandle, !block ? 1 : 0);
		if (ok) {
#if 1
			printf("Playback time = %li.%i, Record time = %li.%i, diff = %li\n",
			       p_tstamp.tv_sec,
			       (int)p_tstamp.tv_usec,
			       c_tstamp.tv_sec,
			       (int)c_tstamp.tv_usec,
			       timediff(p_tstamp, c_tstamp));
#endif
			break;
		}
		snd_pcm_unlink(chandle);
		snd_pcm_hw_free(phandle);
		snd_pcm_hw_free(chandle);
	}
	snd_pcm_close(phandle);
	snd_pcm_close(chandle);
	return 0;
}
Ejemplo n.º 2
0
int main(int argc, char **argv)
{
	bool_t nodaemon = false;
#ifdef POSIX_PRIORITY_SCHEDULING
	bool_t realtime = false;
#endif
	bool_t testconfig = false;
	char *conffile = NULL, *pidfile = NULL;
	int c;
	struct utsname utsbuf;

	/* Arguments */
#ifdef POSIX_PRIORITY_SCHEDULING
	while ((c = getopt(argc, argv, "drp:c:a:A:b:B:ht")) != EOF) {
#else
		while ((c = getopt(argc, argv, "dp:c:a:A:b:B:ht")) != EOF) {
#endif
			switch(c) {
				case 'c':
					conffile = optarg;
					break;
				case 'p':
					pidfile = optarg;
					break;
				case 'a':
					bindaddr = optarg;
					break;
				case 'A':
					bindaddr6 = optarg;
					break;
				case 'b':
					bindport = atoi(optarg);
					break;
				case 'B':
					bindport6 = atoi(optarg);
					break;
				case 'd':
					nodaemon = true;
					break;
				case 'h':
					printhelp();
					break;
				case 't':
					testconfig = true;
					break;
#ifdef POSIX_PRIORITY_SCHEDULING
				case 'r':
					realtime = true;
					break;
#endif
				default:
					fprintf(stderr, "Unrecognized option\n");
					printhelp();
					break;
			}
		}

		if (testconfig) {
			if (!Conf_ok(conffile))
				exit(1);
			else
				exit(0);
		}

		/* Initialize the config subsystem early;
		 * switch_user() will need to read some config variables as well as logging.
		 */
		Conf_init(conffile);

		/* Logging to terminal if not daemonizing, otherwise to syslog or log file.
		*/
		if (!nodaemon) {
			daemonize();
			Log_init(false);
			if (pidfile != NULL)
				lockfile(pidfile);

			switch_user();

			/* Reopen log file. If user switch results in access denied, we catch
			 * it early.
			 */
			Log_reset();
		}
		else Log_init(true);

		signal(SIGCHLD, SIG_IGN); /* ignore child */
		signal(SIGTSTP, SIG_IGN); /* ignore tty signals */
		signal(SIGTTOU, SIG_IGN);
		signal(SIGTTIN, SIG_IGN);
		signal(SIGPIPE, SIG_IGN);
		signal(SIGHUP, signal_handler); /* catch hangup signal */
		signal(SIGTERM, signal_handler); /* catch kill signal */

		/* Build system string */
		if (uname(&utsbuf) == 0) {
			snprintf(system_string, 64, "%s %s", utsbuf.sysname, utsbuf.machine);
			snprintf(version_string, 64, "%s", utsbuf.release);
		}
		else {
			snprintf(system_string, 64, "unknown unknown");
			snprintf(version_string, 64, "unknown");
		}

		/* Initializing */
		SSLi_init();
		Chan_init();
		Client_init();
		Ban_init();
    
#ifdef USE_SHAREDMEMORY_API    
    Sharedmemory_init( bindport, bindport6 );
#endif
   
#ifdef POSIX_PRIORITY_SCHEDULING
		if (realtime)
			setscheduler();
#endif

		Server_run();

#ifdef USE_SHAREDMEMORY_API
    Sharedmemory_deinit();
#endif

		Ban_deinit();
		SSLi_deinit();
		Chan_free();
		Log_free();
		Conf_deinit();

		if (pidfile != NULL)
			unlink(pidfile);

		return 0;
	}
Ejemplo n.º 3
0
static void thread_job1(void *_data)
{
	struct loopback_thread *thread = _data;
	snd_output_t *output = thread->output;
	struct pollfd *pfds = NULL;
	int pfds_count = 0;
	int i, j, err, wake = 1000000;

	setscheduler();

	for (i = 0; i < thread->loopbacks_count; i++) {
		err = pcmjob_init(thread->loopbacks[i]);
		if (err < 0) {
			logit(LOG_CRIT, "Loopback initialization failure.\n");
			my_exit(thread, EXIT_FAILURE);
		}
	}
	for (i = 0; i < thread->loopbacks_count; i++) {
		err = pcmjob_start(thread->loopbacks[i]);
		if (err < 0) {
			logit(LOG_CRIT, "Loopback start failure.\n");
			my_exit(thread, EXIT_FAILURE);
		}
		pfds_count += thread->loopbacks[i]->pollfd_count;
		j = thread->loopbacks[i]->wake;
		if (j > 0 && j < wake)
			wake = j;
	}
	if (wake >= 1000000)
		wake = -1;
	pfds = calloc(pfds_count, sizeof(struct pollfd));
	if (pfds == NULL || pfds_count <= 0) {
		logit(LOG_CRIT, "Poll FDs allocation failed.\n");
		my_exit(thread, EXIT_FAILURE);
	}
	while (!quit) {
		struct timeval tv1, tv2;
		for (i = j = 0; i < thread->loopbacks_count; i++) {
			err = pcmjob_pollfds_init(thread->loopbacks[i], &pfds[j]);
			if (err < 0) {
				logit(LOG_CRIT, "Poll FD initialization failed.\n");
				my_exit(thread, EXIT_FAILURE);
			}
			j += err;
		}
		if (verbose > 10)
			gettimeofday(&tv1, NULL);
		usleep(1000);
		err = poll(pfds, j, wake);
		if (err < 0)
			err = -errno;
		if (verbose > 10) {
			gettimeofday(&tv2, NULL);
			snd_output_printf(output, "pool took %lius\n", timediff(tv2, tv1));
		}
		if (err < 0) {
			if (err == -EINTR || err == -ERESTART)
				continue;
			logit(LOG_CRIT, "Poll failed: %s\n", strerror(-err));
			my_exit(thread, EXIT_FAILURE);
		}
		for (i = j = 0; i < thread->loopbacks_count; i++) {
			struct loopback *loop = thread->loopbacks[i];
			if (j < loop->active_pollfd_count) {
				err = pcmjob_pollfds_handle(loop, &pfds[j]);
				if (err < 0) {
					logit(LOG_CRIT, "pcmjob failed.\n");
					return EXIT_FAILURE;
				}
			}
			j += loop->active_pollfd_count;
		}
	}

	my_exit(thread, EXIT_SUCCESS);
}