stew

a monorepo of some sort
git clone git://git.nsmpr.xyz/stew.git
Log | Files | Refs

piano.c (1660B)


      1 /*
      2  * lets user play samples from PCM files
      3  * using computer keyboard
      4  */
      5 
      6 #include <u.h>
      7 #include <libc.h>
      8 
      9 #define BSIZE 4096
     10 
     11 Rune *keys =  L"zsxdcvgbhnjmq2w3er5t6y7ui9o0p[";
     12 Rune *notes = L"CCDDEFFGGAAB";
     13 Rune *semi  = L"-#-#--#-#-#-";
     14 
     15 /*
     16  * Frequencies for equal-tempered scale
     17  * from https://pages.mtu.edu/~suits/notefreqs.html
     18  */
     19 
     20 double freq[] = {
     21 	261.63, // C-4
     22 	277.18,
     23 	293.66,
     24 	311.13,
     25 	329.63,
     26 	349.23,
     27 	369.99,
     28 	392.00,
     29 	415.30,
     30 	440.00, // A-4
     31 	466.16,
     32 	493.88,
     33 	523.25, // C-5
     34 	554.37,
     35 	587.33,
     36 	622.25,
     37 	659.25,
     38 	698.46,
     39 	739.99,
     40 	783.99,
     41 	830.61,
     42 	880.00, // A-5
     43 	932.33,
     44 	987.77,
     45 	1046.50,
     46 	1108.73,
     47 	1174.66,
     48 	1244.51,
     49 	1318.51,
     50 	1396.91 // F-6
     51 };
     52 
     53 void
     54 usage(void)
     55 {
     56 	fprint(2, "usage: %s\n", argv0);
     57 	exits("usage");
     58 }
     59 
     60 void
     61 main(int argc, char **argv)
     62 {
     63 	int kbd;
     64 	long n;
     65 	char buf[BSIZE];
     66 	Rune last;
     67 
     68 	ARGBEGIN {
     69 	default:
     70 		usage();
     71 	} ARGEND
     72 	if (argc != 0) usage();
     73 
     74 	kbd = open("/dev/kbd", OREAD);
     75 	last = 0;
     76 	while((n = read(kbd, buf, BSIZE)) > 0) {
     77 		char *bp;
     78 		for (bp = buf; bp < buf + n; bp += strlen(bp) + 1) {
     79 			Rune r[BSIZE], *rp;
     80 			runesnprint(r, BSIZE, "%s", bp);
     81 			switch(r[0]) {
     82 			case 'c':
     83 				if  (r[1] == 0x7f) exits(nil);
     84 				break;
     85 			case 'k':
     86 				last = r[runestrlen(r) - 1];
     87 				rp = runestrchr(keys, last);
     88 				if (rp != nil) {
     89 					int k = (rp - keys) % 12;
     90 					int o = (rp - keys) / 12;
     91 					fprint(1, "%C%C%d\n", notes[k], semi[k], o + 3);
     92 				} else {
     93 					if (last == ' ') fprint(1, "k\n");
     94 					last = 0;
     95 				}
     96 				break;
     97 			case 'K':
     98 				if ((last > 0) && (last != r[runestrlen(r) - 1])) {
     99 					// fprint(2, "off\n");
    100 					// fprint(1, "0\n");
    101 					last = 0;
    102 				}
    103 				break;
    104 			}
    105 		}
    106 	}
    107 }
    108