commit 3791f09537852d24498881ab84855582fedf5a6b
parent f10f52f1d5dfa787bd6b1ef53b857fdf57987119
Author: rpa <rpa@laika>
Date: Sat, 24 Dec 2022 21:48:27 +0000
mu: add piano
Diffstat:
2 files changed, 109 insertions(+), 1 deletion(-)
diff --git a/src/mu/mkfile b/src/mu/mkfile
@@ -1,6 +1,6 @@
</$objtype/mkfile
-TARG=trk mubox throttle
+TARG=trk mubox throttle piano
</sys/src/cmd/mkmany
diff --git a/src/mu/piano.c b/src/mu/piano.c
@@ -0,0 +1,108 @@
+/*
+ * lets user play samples from PCM files
+ * using computer keyboard
+ */
+
+#include <u.h>
+#include <libc.h>
+
+#define BSIZE 4096
+
+Rune *keys = L"zsxdcvgbhnjmq2w3er5t6y7ui9o0p[";
+Rune *notes = L"CCDDEFFGGAAB";
+Rune *semi = L"-#-#--#-#-#-";
+
+/*
+ * Frequencies for equal-tempered scale
+ * from https://pages.mtu.edu/~suits/notefreqs.html
+ */
+
+double freq[] = {
+ 261.63, // C-4
+ 277.18,
+ 293.66,
+ 311.13,
+ 329.63,
+ 349.23,
+ 369.99,
+ 392.00,
+ 415.30,
+ 440.00, // A-4
+ 466.16,
+ 493.88,
+ 523.25, // C-5
+ 554.37,
+ 587.33,
+ 622.25,
+ 659.25,
+ 698.46,
+ 739.99,
+ 783.99,
+ 830.61,
+ 880.00, // A-5
+ 932.33,
+ 987.77,
+ 1046.50,
+ 1108.73,
+ 1174.66,
+ 1244.51,
+ 1318.51,
+ 1396.91 // F-6
+};
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+ int kbd;
+ long n;
+ char buf[BSIZE];
+ Rune last;
+
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND
+ if (argc != 0) usage();
+
+ kbd = open("/dev/kbd", OREAD);
+ last = 0;
+ while((n = read(kbd, buf, BSIZE)) > 0) {
+ char *bp;
+ for (bp = buf; bp < buf + n; bp += strlen(bp) + 1) {
+ Rune r[BSIZE], *rp;
+ runesnprint(r, BSIZE, "%s", bp);
+ switch(r[0]) {
+ case 'c':
+ if (r[1] == 0x7f) exits(nil);
+ break;
+ case 'k':
+ last = r[runestrlen(r) - 1];
+ rp = runestrchr(keys, last);
+ if (rp != nil) {
+ int k = (rp - keys) % 12;
+ int o = (rp - keys) / 12;
+ fprint(1, "%C%C%d\n", notes[k], semi[k], o + 3);
+ } else {
+ if (last == ' ') fprint(1, "k\n");
+ last = 0;
+ }
+ break;
+ case 'K':
+ if ((last > 0) && (last != r[runestrlen(r) - 1])) {
+ // fprint(2, "off\n");
+ // fprint(1, "0\n");
+ last = 0;
+ }
+ break;
+ }
+ }
+ }
+}
+