⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amidi.c

📁 ALSA驱动的一些调试测试工具
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (p = send_hex; *p; ++p) {		int digit;		if (isspace((unsigned char)*p)) {			if (value >= 0) {				send_data[i++] = value;				value = -1;			}			continue;		}		digit = hex_value(*p);		if (digit < 0) {			send_data = NULL;			return;		}		if (value < 0) {			value = digit;		} else {			send_data[i++] = (value << 4) | digit;			value = -1;		}	}	if (value >= 0)		send_data[i++] = value;	send_data_length = i;}/* * prints MIDI commands, formatting them nicely */static void print_byte(unsigned char byte){	static enum {		STATE_UNKNOWN,		STATE_1PARAM,		STATE_1PARAM_CONTINUE,		STATE_2PARAM_1,		STATE_2PARAM_2,		STATE_2PARAM_1_CONTINUE,		STATE_SYSEX	} state = STATE_UNKNOWN;	int newline = 0;	if (byte >= 0xf8)		newline = 1;	else if (byte >= 0xf0) {		newline = 1;		switch (byte) {		case 0xf0:			state = STATE_SYSEX;			break;		case 0xf1:		case 0xf3:			state = STATE_1PARAM;			break;		case 0xf2:			state = STATE_2PARAM_1;			break;		case 0xf4:		case 0xf5:		case 0xf6:			state = STATE_UNKNOWN;			break;		case 0xf7:			newline = state != STATE_SYSEX;			state = STATE_UNKNOWN;			break;		}	} else if (byte >= 0x80) {		newline = 1;		if (byte >= 0xc0 && byte <= 0xdf)			state = STATE_1PARAM;		else			state = STATE_2PARAM_1;	} else /* b < 0x80 */ {		int running_status = 0;		newline = state == STATE_UNKNOWN;		switch (state) {		case STATE_1PARAM:			state = STATE_1PARAM_CONTINUE;			break;		case STATE_1PARAM_CONTINUE:			running_status = 1;			break;		case STATE_2PARAM_1:			state = STATE_2PARAM_2;			break;		case STATE_2PARAM_2:			state = STATE_2PARAM_1_CONTINUE;			break;		case STATE_2PARAM_1_CONTINUE:			running_status = 1;			state = STATE_2PARAM_2;			break;		default:			break;		}		if (running_status)			fputs("\n  ", stdout);	}	printf("%c%02X", newline ? '\n' : ' ', byte);}static void sig_handler(int dummy){	stop = 1;}static void add_send_hex_data(const char *str){	int length;	char *s;	length = (send_hex ? strlen(send_hex) + 1 : 0) + strlen(str) + 1;	s = my_malloc(length);	if (send_hex) {		strcpy(s, send_hex);		strcat(s, " ");	} else {		s[0] = '\0';	}	strcat(s, str);	free(send_hex);	send_hex = s;}int main(int argc, char *argv[]){	static const char short_options[] = "hVlLp:s:r:S::dt:a";	static const struct option long_options[] = {		{"help", 0, NULL, 'h'},		{"version", 0, NULL, 'V'},		{"list-devices", 0, NULL, 'l'},		{"list-rawmidis", 0, NULL, 'L'},		{"port", 1, NULL, 'p'},		{"send", 1, NULL, 's'},		{"receive", 1, NULL, 'r'},		{"send-hex", 2, NULL, 'S'},		{"dump", 0, NULL, 'd'},		{"timeout", 1, NULL, 't'},		{"active-sensing", 0, NULL, 'a'},		{ }	};	int c, err, ok = 0;	int ignore_active_sensing = 1;	int do_send_hex = 0;	while ((c = getopt_long(argc, argv, short_options,		     		long_options, NULL)) != -1) {		switch (c) {		case 'h':			usage();			return 0;		case 'V':			version();			return 0;		case 'l':			do_device_list = 1;			break;		case 'L':			do_rawmidi_list = 1;			break;		case 'p':			port_name = optarg;			break;		case 's':			send_file_name = optarg;			break;		case 'r':			receive_file_name = optarg;			break;		case 'S':			do_send_hex = 1;			if (optarg)				add_send_hex_data(optarg);			break;		case 'd':			dump = 1;			break;		case 't':			timeout = atoi(optarg);			break;		case 'a':			ignore_active_sensing = 0;			break;		default:			error("Try `amidi --help' for more information.");			return 1;		}	}	if (do_send_hex) {		/* data for -S can be specified as multiple arguments */		if (!send_hex && !argv[optind]) {			error("Please specify some data for --send-hex.");			return 1;		}		for (; argv[optind]; ++optind)			add_send_hex_data(argv[optind]);	} else {		if (argv[optind]) {			error("%s is not an option.", argv[optind]);			return 1;		}	}	if (do_rawmidi_list)		rawmidi_list();	if (do_device_list)		device_list();	if (do_rawmidi_list || do_device_list)		return 0;	if (!send_file_name && !receive_file_name && !send_hex && !dump) {		error("Please specify at least one of --send, --receive, --send-hex, or --dump.");		return 1;	}	if (send_file_name && send_hex) {		error("--send and --send-hex cannot be specified at the same time.");		return 1;	}	if (send_file_name)		load_file();	else if (send_hex)		parse_data();	if ((send_file_name || send_hex) && !send_data)		return 1;	if (receive_file_name) {		receive_file = creat(receive_file_name, 0666);		if (receive_file == -1) {			error("cannot create %s: %s", receive_file_name, strerror(errno));			return -1;		}	} else {		receive_file = -1;	}	if (receive_file_name || dump)		inputp = &input;	else		inputp = NULL;	if (send_data)		outputp = &output;	else		outputp = NULL;	if ((err = snd_rawmidi_open(inputp, outputp, port_name, SND_RAWMIDI_NONBLOCK)) < 0) {		error("cannot open port \"%s\": %s", port_name, snd_strerror(err));		goto _exit2;	}	if (inputp)		snd_rawmidi_read(input, NULL, 0); /* trigger reading */	if (send_data) {		if ((err = snd_rawmidi_nonblock(output, 0)) < 0) {			error("cannot set blocking mode: %s", snd_strerror(err));			goto _exit;		}		if ((err = snd_rawmidi_write(output, send_data, send_data_length)) < 0) {			error("cannot send data: %s", snd_strerror(err));			goto _exit;		}	}	if (inputp) {		int read = 0;		int npfds, time = 0;		struct pollfd *pfds;		timeout *= 1000;		npfds = snd_rawmidi_poll_descriptors_count(input);		pfds = alloca(npfds * sizeof(struct pollfd));		snd_rawmidi_poll_descriptors(input, pfds, npfds);		signal(SIGINT, sig_handler);		for (;;) {			unsigned char buf[256];			int i, length;			unsigned short revents;			err = poll(pfds, npfds, 200);			if (stop || (err < 0 && errno == EINTR))				break;			if (err < 0) {				error("poll failed: %s", strerror(errno));				break;			}			if (err == 0) {				time += 200;				if (timeout && time >= timeout)					break;				continue;			}			if ((err = snd_rawmidi_poll_descriptors_revents(input, pfds, npfds, &revents)) < 0) {				error("cannot get poll events: %s", snd_strerror(errno));				break;			}			if (revents & (POLLERR | POLLHUP))				break;			if (!(revents & POLLIN))				continue;			err = snd_rawmidi_read(input, buf, sizeof(buf));			if (err == -EAGAIN)				continue;			if (err < 0) {				error("cannot read from port \"%s\": %s", port_name, snd_strerror(err));				break;			}			length = 0;			for (i = 0; i < err; ++i)				if (!ignore_active_sensing || buf[i] != 0xfe)					buf[length++] = buf[i];			if (length == 0)				continue;			read += length;			time = 0;			if (receive_file != -1)				write(receive_file, buf, length);			if (dump) {				for (i = 0; i < length; ++i)					print_byte(buf[i]);				fflush(stdout);			}		}		if (isatty(fileno(stdout)))			printf("\n%d bytes read\n", read);	}	ok = 1;_exit:	if (inputp)		snd_rawmidi_close(input);	if (outputp)		snd_rawmidi_close(output);_exit2:	if (receive_file != -1)		close(receive_file);	return !ok;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -