~rabbits/orca-toy

56383110e33d78c7506418bc6d359d1a283e816c — neauoire 2 years ago 09e6aaa
Progress on midi msg parsing
4 files changed, 169 insertions(+), 148 deletions(-)

M demo.orca
M orca.c
M sim.c
M sim.h
M demo.orca => demo.orca +3 -0
@@ 11,4 11,7 @@
................................
................................
...V....X....Y...1ZC............
................................
....D........D.......D..........
.....:0.......:12.....:23E......
................................
\ No newline at end of file

M orca.c => orca.c +119 -102
@@ 30,6 30,12 @@ typedef struct {
	int x, y, w, h;
} Rect2d;

typedef struct {
	int channel, octave, note, gate;
} Note;

char OCTAVE[] = {'C', 'c', 'D', 'd', 'E', 'F', 'f', 'G', 'g', 'A', 'a', 'B'};

Rect2d cursor;
Grid g;



@@ 37,8 43,6 @@ int WIDTH = 8 * HOR + PAD * 2;
int HEIGHT = 8 * (VER + 2) + PAD * 2;
int FPS = 30, DOWN = 0, ZOOM = 2, PAUSE = 0;

char OCTAVE[] = {'C', 'c', 'D', 'd', 'E', 'F', 'f', 'G', 'g', 'A', 'a', 'B'};

Uint32 theme[] = {
	0x000000,
	0xFFFFFF,


@@ 59,14 63,15 @@ Uint8 icons[][8] = {
	{0x00, 0x38, 0x44, 0x92, 0x28, 0x10, 0x00, 0x00}  /* eye closed */
};

char clip[1024];
Uint8 font[1200];
Note playing[16];

SDL_Window *gWindow = NULL;
SDL_Renderer *gRenderer = NULL;
SDL_Texture *gTexture = NULL;
Uint32 *pixels;
PmStream *midi;
char clip[1024];

int
clamp(int val, int min, int max)


@@ 241,105 246,6 @@ scale(int w, int h)
	select(cursor.x, cursor.y, cursor.w + w, cursor.h + h);
}

int
getoffset(int o, char n)
{
	int i;
	for(i = 0; i < 12; ++i)
		if(n == OCTAVE[i])
			return o * 12 + i;
	return 0;
}

int
getnote(int o, char n)
{
	int offset = 0;
	switch(n) {
	case 'A': offset = getoffset(0, 'A'); break;
	case 'a': offset = getoffset(0, 'a'); break;
	case 'B': offset = getoffset(0, 'B'); break;
	case 'C': offset = getoffset(0, 'C'); break;
	case 'c': offset = getoffset(0, 'c'); break;
	case 'D': offset = getoffset(0, 'D'); break;
	case 'd': offset = getoffset(0, 'd'); break;
	case 'E': offset = getoffset(0, 'E'); break;
	case 'F': offset = getoffset(0, 'F'); break;
	case 'f': offset = getoffset(0, 'f'); break;
	case 'G': offset = getoffset(0, 'G'); break;
	case 'g': offset = getoffset(0, 'g'); break;
	case 'H': offset = getoffset(0, 'A'); break;
	case 'h': offset = getoffset(0, 'a'); break;
	case 'I': offset = getoffset(0, 'B'); break;
	case 'J': offset = getoffset(1, 'C'); break;
	case 'j': offset = getoffset(1, 'c'); break;
	case 'K': offset = getoffset(1, 'D'); break;
	case 'k': offset = getoffset(1, 'd'); break;
	case 'L': offset = getoffset(1, 'E'); break;
	case 'M': offset = getoffset(1, 'F'); break;
	case 'm': offset = getoffset(1, 'f'); break;
	case 'N': offset = getoffset(1, 'G'); break;
	case 'n': offset = getoffset(1, 'g'); break;
	case 'O': offset = getoffset(1, 'A'); break;
	case 'o': offset = getoffset(1, 'a'); break;
	case 'P': offset = getoffset(1, 'B'); break;
	case 'Q': offset = getoffset(2, 'C'); break;
	case 'q': offset = getoffset(2, 'c'); break;
	case 'R': offset = getoffset(2, 'D'); break;
	case 'r': offset = getoffset(2, 'd'); break;
	case 'S': offset = getoffset(2, 'E'); break;
	case 'T': offset = getoffset(2, 'F'); break;
	case 't': offset = getoffset(2, 'f'); break;
	case 'U': offset = getoffset(2, 'G'); break;
	case 'u': offset = getoffset(2, 'g'); break;
	case 'V': offset = getoffset(2, 'A'); break;
	case 'v': offset = getoffset(2, 'a'); break;
	case 'W': offset = getoffset(2, 'B'); break;
	case 'X': offset = getoffset(3, 'C'); break;
	case 'x': offset = getoffset(3, 'c'); break;
	case 'Y': offset = getoffset(3, 'D'); break;
	case 'y': offset = getoffset(3, 'd'); break;
	case 'Z': offset = getoffset(3, 'E'); break;
	case 'e': offset = getoffset(0, 'F'); break;
	case 'l': offset = getoffset(1, 'F'); break;
	case 's': offset = getoffset(2, 'F'); break;
	case 'z': offset = getoffset(3, 'F'); break;
	case 'b': offset = getoffset(1, 'C'); break;
	case 'i': offset = getoffset(1, 'C'); break;
	case 'p': offset = getoffset(2, 'C'); break;
	case 'w': offset = getoffset(3, 'C'); break;
	}
	return o + offset;
}

void
playmidi(int channel, int octave, int note)
{
	Pm_WriteShort(midi,
		Pt_Time(),
		Pm_Message(0x90 + channel, (octave * 12) + note, 100));
	Pm_WriteShort(midi,
		Pt_Time(),
		Pm_Message(0x90 + channel, (octave * 12) + note, 0));
	printf("%d -> %d\n", channel, (octave * 12) + note);
	fflush(stdout);
}

void
play(void)
{
	int i;
	for(i = 0; i < g.msg_len; ++i) {
		char c, o, n;
		if(i < 1 || g.msg[i - 1] != ':')
			continue;
		if(sscanf(g.msg + 1, "%c%c%c", &c, &o, &n) > 0) {
			playmidi(c - '0', o - '0', getnote(o - '0', n));
			i += 3;
		}
	}
}

void
selectoption(int option)
{


@@ 407,6 313,117 @@ moveclip(Rect2d *r, char *c, int x, int y)
	pasteclip(r, c);
}

/* midi */

int
nteval(int o, char c)
{
	switch(c) {
	case 'A': return 9;
	case 'a': return 10;
	case 'B': return 11;
	case 'b':
	case 'C': return 0;
	case 'c': return 1;
	case 'D': return 2;
	case 'd': return 3;
	case 'E': return 4;
	case 'e':
	case 'F': return 5;
	case 'f': return 6;
	case 'G': return 7;
	case 'g': return 8;
	default:
		if(c >= '0' && c <= '9')
			return c - '0';
		else
			return nteval(o + 12, c - 7);
	}
	return 0;
}

Note *
setnote(Note *n, int channel, int octave, int note, int gate)
{
	n->channel = channel;
	n->octave = octave;
	n->note = note;
	n->gate = gate;
	return n;
}

Note *
pushmidi(int chn, int val, int vel, int len)
{
	printf("%d %d %d %d\n", chn, val, vel, len);
	/*
	int i = 0;
	for(i = 0; i < 16; ++i)
		if(!playing[i].gate)
			return setnote(&playing[i], channel, octave, note, gate);
	return NULL;
	*/
	return NULL;
}

void
playmidi(int channel, int octave, int note, int len)
{
	Pm_WriteShort(midi,
		Pt_Time(),
		Pm_Message(0x90 + channel, (octave * 12) + note, 100));
	Pm_WriteShort(midi,
		Pt_Time(),
		Pm_Message(0x90 + channel, (octave * 12) + note, 0));
	printf("%d -> %d\n", channel, (octave * 12) + note);
	pushmidi(channel, octave, note, len);
	fflush(stdout);
}

void
parsemidi(char *msg, int msglen)
{
	char chn, oct, nte, vel = 'z', len = '1';
	if(msglen < 3)
		return;
	chn = msg[0];
	oct = msg[1];
	nte = msg[2];
	if(msglen > 3)
		vel = msg[3];
	if(msglen > 4)
		len = msg[4];
	pushmidi(
		base36(chn),
		12 * base36(oct) + nteval(0, nte),
		base36(vel),
		base36(len));
}

void
play(void)
{
	int i, j = 0;
	char buf[128];
	/* release */
	for(i = 0; i < 16; ++i) {
		if(playing[i].gate > 0) {
			playing[i].gate--;
			printf("release: #%d[%d]\n", i, playing[i].gate);
		}
	}
	/* split messages */
	for(i = 0; i < g.msg_len + 1; ++i)
		if(!g.msg[i] || cisp(g.msg[i])) {
			buf[j] = '\0';
			parsemidi(buf, j);
			j = 0;
		} else
			buf[j++] = g.msg[i];
}

/* triggers */

void
domouse(SDL_Event *event)
{

M sim.c => sim.c +44 -46
@@ 31,20 31,6 @@ clca(int c)
	return ciuc(c) ? c + ('a' - 'A') : c;
}

int
cint(char c)
{
	if(c == '.')
		return 0;
	if(cinu(c))
		return c - '0';
	if(cilc(c))
		return c - 'a' + 10;
	if(ciuc(c))
		return c - 'A' + 10;
	return 0;
}

char
cchr(int v, int cap)
{


@@ 74,6 60,18 @@ random(Grid *g)
	*/
}

int
base36(char c)
{
	if(c >= 'A' && c <= 'Z')
		return c - 'A' + 10;
	if(c >= 'a' && c <= 'z')
		return c - 'a' + 10;
	if(c >= '0' && c <= '9')
		return c - '0';
	return 0;
}

/* IO */

char


@@ 96,13 94,13 @@ set(Grid *g, int x, int y, char c)
void
save(Grid *g, char key, char val)
{
	g->vars[cint(key)] = val;
	g->vars[base36(key)] = val;
}

char
load(Grid *g, char key)
{
	return g->vars[cint(key)];
	return g->vars[base36(key)];
}

/* Syntax */


@@ 168,7 166,7 @@ opa(Grid *g, int x, int y, char c)
{
	char a = getport(g, x - 1, y, 0);
	char b = getport(g, x + 1, y, 1);
	setport(g, x, y + 1, cchr(cint(a) + cint(b), ciuc(b)));
	setport(g, x, y + 1, cchr(base36(a) + base36(b), ciuc(b)));
	(void)c;
}



@@ 177,7 175,7 @@ opb(Grid *g, int x, int y, char c)
{
	char a = getport(g, x - 1, y, 0);
	char b = getport(g, x + 1, y, 1);
	setport(g, x, y + 1, cchr(cint(a) - cint(b), ciuc(b)));
	setport(g, x, y + 1, cchr(base36(a) - base36(b), ciuc(b)));
	(void)c;
}



@@ 186,8 184,8 @@ opc(Grid *g, int x, int y, char c)
{
	char rate = getport(g, x - 1, y, 0);
	char mod = getport(g, x + 1, y, 1);
	int mod_ = cint(mod);
	int rate_ = cint(rate);
	int mod_ = base36(mod);
	int rate_ = base36(rate);
	if(!rate_)
		rate_ = 1;
	if(!mod_)


@@ 201,8 199,8 @@ opd(Grid *g, int x, int y, char c)
{
	char rate = getport(g, x - 1, y, 0);
	char mod = getport(g, x + 1, y, 1);
	int rate_ = cint(rate);
	int mod_ = cint(mod);
	int rate_ = base36(rate);
	int mod_ = base36(mod);
	if(!rate_)
		rate_ = 1;
	if(!mod_)


@@ 239,11 237,11 @@ opg(Grid *g, int x, int y, char c)
	char px = getport(g, x - 3, y, 0);
	char py = getport(g, x - 2, y, 0);
	char len = getport(g, x - 1, y, 0);
	int i, len_ = cint(len);
	int i, len_ = base36(len);
	if(!len_)
		len_ = 1;
	for(i = 0; i < len_; ++i)
		setport(g, x + i + cint(px), y + 1 + cint(py), getport(g, x + 1 + i, y, 1));
		setport(g, x + i + base36(px), y + 1 + base36(py), getport(g, x + 1 + i, y, 1));
	(void)c;
}



@@ 260,13 258,13 @@ opi(Grid *g, int x, int y, char c)
	char rate = getport(g, x - 1, y, 0);
	char mod = getport(g, x + 1, y, 1);
	char val = getport(g, x, y + 1, 1);
	int rate_ = cint(rate);
	int mod_ = cint(mod);
	int rate_ = base36(rate);
	int mod_ = base36(mod);
	if(!rate_)
		rate_ = 1;
	if(!mod_)
		mod_ = 36;
	setport(g, x, y + 1, cchr((cint(val) + rate_) % mod_, ciuc(mod)));
	setport(g, x, y + 1, cchr((base36(val) + rate_) % mod_, ciuc(mod)));
	(void)c;
}



@@ 287,7 285,7 @@ void
opk(Grid *g, int x, int y, char c)
{
	char len = getport(g, x - 1, y, 0);
	int i, len_ = cint(len);
	int i, len_ = base36(len);
	if(!len_)
		len_ = 1;
	for(i = 0; i < len_; ++i) {


@@ 303,7 301,7 @@ opl(Grid *g, int x, int y, char c)
{
	char a = getport(g, x - 1, y, 0);
	char b = getport(g, x + 1, y, 1);
	setport(g, x, y + 1, cint(a) < cint(b) ? a : b);
	setport(g, x, y + 1, base36(a) < base36(b) ? a : b);
	(void)c;
}



@@ 312,7 310,7 @@ opm(Grid *g, int x, int y, char c)
{
	char a = getport(g, x - 1, y, 0);
	char b = getport(g, x + 1, y, 1);
	setport(g, x, y + 1, cchr(cint(a) * cint(b), ciuc(b)));
	setport(g, x, y + 1, cchr(base36(a) * base36(b), ciuc(b)));
	(void)c;
}



@@ 334,7 332,7 @@ opo(Grid *g, int x, int y, char c)
{
	char px = getport(g, x - 2, y, 0);
	char py = getport(g, x - 1, y, 0);
	setport(g, x, y + 1, getport(g, x + 1 + cint(px), y + cint(py), 1));
	setport(g, x, y + 1, getport(g, x + 1 + base36(px), y + base36(py), 1));
	(void)c;
}



@@ 344,12 342,12 @@ opp(Grid *g, int x, int y, char c)
	char key = getport(g, x - 2, y, 0);
	char len = getport(g, x - 1, y, 0);
	char val = getport(g, x + 1, y, 1);
	int i, len_ = cint(len);
	int i, len_ = base36(len);
	if(!len_)
		len_ = 1;
	for(i = 0; i < len_; ++i)
		lock(g, x + i, y + 1);
	setport(g, x + (cint(key) % len_), y + 1, val);
	setport(g, x + (base36(key) % len_), y + 1, val);
	(void)c;
}



@@ 359,11 357,11 @@ opq(Grid *g, int x, int y, char c)
	char px = getport(g, x - 3, y, 0);
	char py = getport(g, x - 2, y, 0);
	char len = getport(g, x - 1, y, 0);
	int i, len_ = cint(len);
	int i, len_ = base36(len);
	if(!len_)
		len_ = 1;
	for(i = 0; i < len_; ++i)
		setport(g, x + 1 - len_ + i, y + 1, getport(g, x + 1 + cint(px) + i, y + cint(py), 1));
		setport(g, x + 1 - len_ + i, y + 1, getport(g, x + 1 + base36(px) + i, y + base36(py), 1));
	(void)c;
}



@@ 372,9 370,9 @@ opr(Grid *g, int x, int y, char c)
{
	char min = getport(g, x - 1, y, 0);
	char max = getport(g, x + 1, y, 1);
	int min_ = cint(min);
	int max_ = cint(max);
	setport(g, x, y + 1, cchr((random(g) % ((cint(max_) - min_) || 1)) + min_, ciuc(max)));
	int min_ = base36(min);
	int max_ = base36(max);
	setport(g, x, y + 1, cchr((random(g) % ((base36(max_) - min_) || 1)) + min_, ciuc(max)));
	(void)c;
}



@@ 396,12 394,12 @@ opt(Grid *g, int x, int y, char c)
{
	char key = getport(g, x - 2, y, 0);
	char len = getport(g, x - 1, y, 0);
	int i, len_ = cint(len);
	int i, len_ = base36(len);
	if(!len_)
		len_ = 1;
	for(i = 0; i < len_; ++i)
		lock(g, x + 1 + i, y);
	setport(g, x, y + 1, getport(g, x + 1 + (cint(key) % len_), y, 1));
	setport(g, x, y + 1, getport(g, x + 1 + (base36(key) % len_), y, 1));
	(void)c;
}



@@ 410,8 408,8 @@ opu(Grid *g, int x, int y, char c)
{
	char step = getport(g, x - 1, y, 1);
	char max = getport(g, x + 1, y, 1);
	int step_ = cint(step);
	int max_ = cint(max);
	int step_ = base36(step);
	int max_ = base36(max);
	int bucket;
	if(!step_)
		step_ = 1;


@@ 453,7 451,7 @@ opx(Grid *g, int x, int y, char c)
	char px = getport(g, x - 2, y, 0);
	char py = getport(g, x - 1, y, 0);
	char val = getport(g, x + 1, y, 1);
	setport(g, x + cint(px), y + cint(py) + 1, val);
	setport(g, x + base36(px), y + base36(py) + 1, val);
	(void)c;
}



@@ 476,9 474,9 @@ opz(Grid *g, int x, int y, char c)
	char rate = getport(g, x - 1, y, 0);
	char target = getport(g, x + 1, y, 1);
	char val = getport(g, x, y + 1, 1);
	int rate_ = cint(rate);
	int target_ = cint(target);
	int val_ = cint(val);
	int rate_ = base36(rate);
	int target_ = base36(target);
	int val_ = base36(val);
	int mod;
	if(!rate_)
		rate_ = 1;

M sim.h => sim.h +3 -0
@@ 10,6 10,9 @@ typedef struct Grid {
	char data[MAXSZ], vars[36], msg[16];
} Grid;

int base36(char c);
int cisp(char c);

char get(Grid *g, int x, int y);
void set(Grid *g, int x, int y, char c);
int gettype(Grid *g, int x, int y);