stew

a monorepo of some sort
Log | Files | Refs

commit ec8e5b1a049d2bd216c8df94d406d1193e0fe373
parent 513a920f614d38381fc1733aef5f9f7885d53aaa
Author: glenda <glenda@kobeni>
Date:   Sat, 27 Jan 2024 17:28:06 +0000

src/midi: move piano from wave

Diffstat:
Msrc/midi/dump.c | 7+++----
Msrc/midi/midi.c | 19+++++++++++++++++++
Msrc/midi/midi.h | 2++
Msrc/midi/mkfile | 2+-
Asrc/midi/piano.c | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/wave/mkfile | 2+-
Dsrc/wave/piano.c | 65-----------------------------------------------------------------
7 files changed, 127 insertions(+), 71 deletions(-)

diff --git a/src/midi/dump.c b/src/midi/dump.c @@ -20,10 +20,9 @@ noteoff(MidiMes m) void main(void) { - char buf[256]; - int i, n; + char buf[4]; MidiMes m; - while ((n = read(0, buf, 256)) > 0) { + while (read(0, buf, 4) >= 4) { midifill(&m, buf, 4); switch(m.status) { case NOTE_ON: @@ -33,7 +32,7 @@ main(void) noteoff(m); break; default: - print("%x %x | %x %x | %02x %02x\n", + print("%ux %ux | %ux %ux | %02ux %02ux\n", m.cn, m.cin, m.status, m.channel, m.param[0], m.param[1]); } diff --git a/src/midi/midi.c b/src/midi/midi.c @@ -1,6 +1,7 @@ #include <u.h> #include <libc.h> #include "midi.h" + char * midifill(MidiMes *m, char *p, int) { @@ -12,3 +13,21 @@ midifill(MidiMes *m, char *p, int) m->param[1] = p[3]; return p + 4; } + +void +midinoteon(char *p, int chan, int note, int velocity) +{ + p[0] = CIN_NoteOn; + p[1] = (chan & 0x0f) | (NOTE_ON); + p[2] = note; + p[3] = velocity; +} + +void +midinoteoff(char *p, int chan, int note, int velocity) +{ + p[0] = CIN_NoteOff; + p[1] = (chan & 0x0f) | (NOTE_OFF); + p[2] = note; + p[3] = velocity; +} diff --git a/src/midi/midi.h b/src/midi/midi.h @@ -37,3 +37,5 @@ struct MidiMes { }; char * midifill(MidiMes *, char *, int); +void midinoteon(char *, int, int, int); +void midinoteoff(char *, int, int, int); diff --git a/src/midi/mkfile b/src/midi/mkfile @@ -1,5 +1,5 @@ </$objtype/mkfile -TARG=dump +TARG=dump piano HFILES=midi.h OFILES=midi.$O </sys/src/cmd/mkmany diff --git a/src/midi/piano.c b/src/midi/piano.c @@ -0,0 +1,101 @@ +/* + * kbd in, midi out + */ + +#include <u.h> +#include <libc.h> + +#include "midi.h" + +enum { + BSIZE = 128, + ROSIZE = 32, +}; + +Rune *keys = L"zsxdcvgbhnjmq2w3er5t6y7ui9o0p["; +Rune *notes = L"CCDDEFFGGAAB"; +Rune *semi = L"-#-#--#-#-#-"; + +char m[4]; + +typedef struct MKey MKey; +struct MKey { + Rune r; + int state; + int count; +}; + +MKey ro[ROSIZE]; + +int octave = 4; +int channel = 0, velocity = 127; + +int +key2note(int n) +{ + return octave * 12 + n; +} + +void +usage(void) +{ + fprint(2, "usage: %s\n", argv0); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + int i, rn, kbd; + long n; + char buf[BSIZE]; + + ARGBEGIN { + default: + usage(); + } ARGEND + if (argc != 0) usage(); + + kbd = open("/dev/kbd", OREAD); + 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': //character out + if (r[1] == 0x7f) exits(nil); + break; + case 'k': /* key on */ + for (i = 0; i < runestrlen(r); i++) { + if ((rp = runestrchr(keys, r[i])) == nil) continue; + rn = rp - keys; + if (ro[rn].state == 0) { + ro[rn].state = 1; + // fprint(2, "key on: %d\n", key2note(rn)); + midinoteon(m, channel, key2note(rn), velocity); + write(1, m, 4); + } + } + break; + case 'K': /* key off */ + for (i = 0; i < ROSIZE; i++) ro[i].count = 0; + for (i = 0; i < runestrlen(r); i++) { + if ((rp = runestrchr(keys, r[i])) == nil) continue; + rn = rp - keys; + ro[rn].count = 1; + } + for (i = 0; i < ROSIZE; i++) { + if (ro[i].state == 0) continue; + if (ro[i].count == 0) { + ro[i].state = 0; + // fprint(2, "key off: %d\n", key2note(i)); + midinoteoff(m, channel, key2note(i), velocity); + write(1, m, 4); + } + } + break; + } + } + } +} diff --git a/src/wave/mkfile b/src/wave/mkfile @@ -1,6 +1,6 @@ </$objtype/mkfile -TARG=draw loop fade piano sampler harm smoke inst wfedit track +TARG=draw loop fade sampler harm smoke inst wfedit track BIN=/$objtype/bin HFILES=util.h wavetable.h prog.h OFILES=wavetable.$O prog.$O util.$O diff --git a/src/wave/piano.c b/src/wave/piano.c @@ -1,65 +0,0 @@ -/* - * lets user play samples from PCM files - * using computer keyboard - */ - -#include <u.h> -#include <libc.h> - -#include "util.h" - -#define BSIZE 4096 - -Rune *keys = L"zsxdcvgbhnjmq2w3er5t6y7ui9o0p["; -Rune *notes = L"CCDDEFFGGAAB"; -Rune *semi = L"-#-#--#-#-#-"; - -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) { - fprint(1, "%f\n", note2freq(rp-keys)); - } else last = 0; - break; - case 'K': - if ((last > 0) && (last != r[runestrlen(r) - 1])) { - fprint(1, "0\n"); - last = 0; - } - break; - } - } - } -}