Tom Buskey <t...@buskey.name> writes:
> Does the USB HID simultaneous key limit apply to a MIDI-> usb adapter?
> They adapters are pretty cheap nowadays.
>
> Then you need a your chording keyboard to speak MIDI.

So this is interesting. Evan, the one commissioned to write the program,
reported that he could only get *3* simultaneous keys out. I tried my
semi-independent program and I can partially confirm this. I can always
get 3, but if I choose carefully I can get up to 6. I have to...scatter
the keys across the keyboard more evenly? Or choose different rows? I'm
not sure what the pattern is yet, although it doesn't matter because:

Kyle's scheme needs at least 7 but he'd prefer 10 keys. So maybe MIDI is
the way to go. Or PS2, if I can find a keyboard and a hole to plug it
into. Oh wait, HIS computer has PS2, so that's OK. And the flea
market/freecycle/people at work probably have tons of PS2 keyboards
they'd love to give away.

Oh ho ho! His computer actually *has* a PS2 keyboard already attached!
Imma try it now.

...

Huh, that doesn't really work either. I can get up to 6, but I still
have to choose carefully (or something). Maybe the Linux keyboard driver
is the real problem? Or the keyboard hardware itself? Or maybe just my
program, which I will admit is hacked together.

I'm attaching it for comment. I based it on something I found
online. Compile with 

    gcc -o keychord keychord.c -lncurses

and run like

    sudo ./keychord /dev/input/<where ever you kbd event dealie is>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>
#include <ncurses.h>

void handler (int sig)
{
	printf ("nexiting...(%d)n", sig);
	exit (0);
}

void perror_exit (char *error)
{
	perror (error);
	handler (9);
}

int main (int argc, char *argv[])
{
	struct input_event ev[64];
	int fd, rd, value, size = sizeof (struct input_event),
		kbdwidth=15, row, col;
	char name[256] = "Unknown", ch;
	char *device = NULL;

	//Setup check
	if (argv[1] == NULL){
		printf("Please specify (on the command line) the path to the dev event interface devicen");
		exit (0);
	 }

	if ((getuid ()) != 0)
		printf ("You are not root! This may not work...n");

	if (argc > 1)
		device = argv[1];

	//Open Device
	if ((fd = open (device, O_RDONLY)) == -1)
		printf ("%s is not a vaild device.n", device);

	//Print Device Name
	ioctl (fd, EVIOCGNAME (sizeof (name)), name);
	printf ("Reading From : %s (%s)n", device, name);

	fflush(stdout);

	initscr();
	noecho();
	curs_set(0);
	refresh();
	while (1){
		/* seems to be some junk (bounce?) in the first event and the
		   third one is always 0, so just use the second */
		if ((rd = read (fd, ev, size * 3)) < size)
			perror_exit ("read()");

		/* printw("--------\n"); */
		/* printw("type (1 = a key event): %u\n", ev[1].type); */
		/* printw("code (key code, see linux/input.h): %u\n", ev[1].code); */
		/* printw("value (0 = up, 1 = down): %d\n", ev[1].value); */

		if (ev[1].type != 1) continue;

		// keycodes seem to roughly follow layout on actual keyboard
		row = 4*(ev[1].code/kbdwidth);
		col = 10*(ev[1].code % kbdwidth);
		switch(ev[1].code) {
		  case KEY_A: ch = 'a'; break;
		  case KEY_B: ch = 'b'; break;
		  case KEY_C: ch = 'c'; break;
		  case KEY_D: ch = 'd'; break;
		  case KEY_E: ch = 'e'; break;
			  // absolutely no idea why KEY_F doesn't work...
		  case 33: ch = 'f'; break;
		  case KEY_G: ch = 'g'; break;
		  case KEY_H: ch = 'h'; break;
		  case KEY_I: ch = 'i'; break;
		  case KEY_J: ch = 'j'; break;
		  case KEY_K: ch = 'k'; break;
		  case KEY_L: ch = 'l'; break;
		  case KEY_M: ch = 'm'; break;
		  case KEY_N: ch = 'n'; break;
		  case KEY_O: ch = 'o'; break;
		  case KEY_P: ch = 'p'; break;
		  case KEY_Q: ch = 'q'; break;
		  case KEY_R: ch = 'r'; break;
		  case KEY_S: ch = 's'; break;
		  case KEY_T: ch = 't'; break;
		  case KEY_U: ch = 'u'; break;
		  case KEY_V: ch = 'v'; break;
		  case KEY_W: ch = 'w'; break;
		  case KEY_X: ch = 'x'; break;
		  case KEY_Y: ch = 'y'; break;
		  case KEY_Z: ch = 'z'; break;
		  default: ch = ' ';
		}

		mvaddch(row, col, ch|(ev[1].value?A_REVERSE:0));

		refresh();
	}
	endwin();

	return 0;
}
Really, there should be no limitation. I guess it's because they
keyboard has to report "repeat" when you hold a key down. But with our
own electronics, we can define the protocol to just detect edges, so no
numerical limit would exist--just send one at a time, every time.
_______________________________________________
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/

Reply via email to