リスト2-6-3.txt

■リスト2-6-3■

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <time.h>
#include <math.h>
#include <neuron.h>
#include <fcntl.h>
#include <graph.h>

#define	INPUTUNIT	2
#define	HIDDENUNIT	16
#define	OUTPUTUNIT	2
#define	BIASUNIT	1
#define	ERROR		-1

#define STATPT  	0xe0d2
#define DATAPT  	0xe0d0
#define DRR     	0x0040
#define DSR     	0x0080
#define PUT		8888
#define GET		9999

#define entry_table		0x0080
#define vector_offset_wave 	1
#define vector_offset_w_block	2
#define vector_offset_user_com	10
#define vector_offset_w_bank   	16

static	union REGS inregs,outregs;
static 	struct SREGS segregs;
int	moux,mouy,right,left,old_l,old_r,old_x,old_y;

double	Eta=0.8,Alpha=0.7;
time_t	ltime;
FILE	*fds,*fdo;

double	pattern[16][INPUTUNIT],teacher[16][OUTPUTUNIT],wc[512];
char	dum[50],number[2],name[16];
int	num,ww,wk,wt,kn[16],le[16],xp[16],yp[16];
unsigned char wb[512],wd[512];

unsigned char patch[577] = {
	0x1C,0x66,0x29,0xEB,0xE1,0xFE,0x37,0x00,0xEB,0xE3,0xFE,0x37,
	0x00,0xEB,0xE2,0xFE,0x37,0x00,0xEB,0xE4,0xFE,0x37,0x00,0x1C,
	0xA4,0x41,0x1C,0x20,0x41,0xC8,0xF8,0x47,0x7F,0x77,0x7D,0xFE,
	0xD6,0x39,0x00,0x70,0xF9,0x70,0xE2,0x28,0xEF,0x76,0x20,0x97,
	0x7F,0xAC,0x80,0xC6,0x04,0x3F,0x7F,0x00,0x00,0xF8,0xAF,0xC6,
	0x1F,0xF8,0x6F,0xF0,0xC7,0x0B,0xF8,0x6F,0xF8,0xFE,0xD6,0xFE,
	0xDF,0x37,0x78,0x00,0x1E,0x20,0xF8,0x6C,0xF0,0xEF,0x78,0x20,
	0x6C,0x0F,0x2F,0x77,0x37,0x7A,0x00,0x1E,0x27,0x78,0x6F,0x00,
	0xFE,0xD6,0xEF,0x7A,0x6F,0x00,0xCE,0x0C,0x6F,0xC0,0xC6,0x0F,
	0x6F,0xD0,0xC6,0x1F,0x37,0x7A,0x01,0x1E,0x37,0x7A,0x00,0x37,
	0x78,0x00,0x1E,0xEF,0x77,0x6F,0x0F,0xFE,0xDE,0x3A,0x00,0x68,
	0xE3,0xE1,0xFE,0x2E,0xF7,0x20,0xE3,0xE1,0xFE,0x87,0x1E,0xEF,
	0x77,0x6F,0x0F,0xFE,0xDE,0x3A,0x00,0x6A,0xE3,0xE3,0xFE,0x2E,
	0xF7,0x20,0xE3,0xE3,0xFE,0x87,0x1E,0xA8,0x62,0xCE,0x08,0xA9,
	0x62,0xFE,0xD6,0xB1,0x62,0xC8,0x08,0xB0,0x62,0x1C,0x46,0x04,
	0x1C,0xBB,0x41,0x27,0xF1,0x1E,0x27,0x5F,0x6C,0xF0,0xA7,0xA7,
	0xA7,0x3A,0xC9,0x41,0xF3,0x4A,0xEA,0xC8,0x58,0x11,0x58,0x11,
	0x58,0x11,0x41,0x12,0xE9,0x12,0xE9,0x12,0xE9,0x12,0xE9,0x12,
	0x7F,0x13,0xDC,0x13,0xE9,0x41,0x8C,0x14,0xF2,0x14,0x3F,0x15,
	0x1C,0x16,0xC3,0x16,0x27,0x5F,0xFE,0xAB,0xEB,0x19,0x14,0xC6,
	0x6C,0x07,0xA6,0x3A,0xFB,0x41,0xF3,0x4A,0xEA,0xC8,0x1C,0x43,
	0x51,0x42,0x0B,0x42,0x2A,0x14,0x33,0x14,0x41,0x14,0x4F,0x14,
	0x84,0x14,0xE3,0xE2,0xFE,0x2E,0xE3,0xE1,0xFE,0x67,0xCE,0x10,
	0xE3,0xE4,0xFE,0x2E,0xE3,0xE3,0xFE,0x67,0xCE,0x1C,0x30,0xFF,
	0x1C,0x48,0x04,0x1E,0x30,0xCF,0x1C,0x48,0x04,0x3A,0x00,0x68,
	0xE3,0xE2,0xFE,0x2E,0xF3,0x28,0xE3,0xE2,0xFE,0x87,0x1C,0x48,
	0x04,0x1E,0x30,0xDF,0x1C,0x48,0x04,0x3A,0x00,0x6A,0xE3,0xE4,
	0xFE,0x2E,0xF3,0x28,0xE3,0xE4,0xFE,0x87,0x1C,0x48,0x04,0x1E,
	0x27,0xF1,0xA9,0x62,0xC6,0xFC,0xB1,0x62,0x27,0x60,0xEB,0xE5,
	0xFE,0x26,0x27,0xF1,0xA9,0x62,0xC6,0xFC,0xB1,0x62,0x27,0x60,
	0xEB,0xE6,0xFE,0x26,0x33,0x00,0x1C,0x79,0x42,0x83,0xFB,0x6F,
	0x10,0xCE,0xF7,0x1E,0x30,0xFA,0xFB,0x31,0xF9,0x6E,0xC0,0xE8,
	0x37,0xF0,0xFB,0x31,0xF9,0x6E,0xD0,0xE8,0x37,0x0F,0xE3,0xE6,
	0xFE,0x28,0x31,0x48,0xF8,0x6A,0x02,0x35,0x20,0xF8,0x12,0x30,
	0x00,0xF8,0x70,0x31,0x08,0xF8,0x70,0xFC,0x6E,0x90,0x30,0xFA,
	0xE2,0x2E,0xFB,0x31,0xE8,0x26,0xFC,0x6C,0x0F,0xFC,0x6E,0xA0,
	0xE2,0x2E,0xFB,0x31,0xF9,0x6E,0x10,0xE8,0x26,0xFC,0x6E,0x10,
	0xE2,0x2E,0xFB,0x31,0xF9,0x6E,0x20,0xE8,0x26,0xFB,0x31,0xF9,
	0x6E,0x30,0xE8,0x37,0x00,0xFB,0x31,0xF9,0x6E,0x40,0xE8,0x37,
	0x00,0xE3,0xE5,0xFE,0x2E,0xFB,0x60,0xFB,0x31,0xF9,0x6E,0x50,
	0xE8,0x26,0xFB,0x31,0xF9,0x6E,0x60,0xE8,0x37,0x80,0xFB,0x31,
	0xF9,0x6E,0x70,0xE8,0x37,0x00,0xFB,0x31,0xF9,0x6E,0xA0,0xE8,
	0x37,0x0F,0xFB,0x31,0xF9,0x6E,0xB0,0xE8,0x37,0x0F,0xFB,0x31,
	0xF9,0x6E,0xC0,0xE8,0x37,0x0F,0xFB,0x31,0xF9,0x6E,0xD0,0xE8,
	0x37,0x0F,0xFB,0x31,0xF9,0x6E,0x90,0xE8,0x37,0x03,0x1E,0x33,
	0x00,0x1C,0x27,0x43,0x83,0xFB,0x6F,0x10,0xCE,0xF7,0x30,0xFA,
	0xFB,0x31,0xF9,0x6E,0xC0,0xE8,0x37,0xF0,0xFB,0x31,0xF9,0x6E,
	0xD0,0xE8,0x37,0x0F,0xFB,0x31,0xF9,0x6E,0x90,0xE8,0x37,0x00,
	0x1E };
unsigned char speed_get_7[66] = {
	0x27,0xF1,0xA9,0x62,0xC6,0xFC,0xB1,0x62,0xE7,0x60,0x28,0x27,0xF1,0xA9,
	0x62,0xC6,0xFC,0xB1,0x62,0xE7,0x60,0x29,0x27,0xF1,0xA9,0x62,0xC6,0xFC,
	0xB1,0x62,0xE7,0x60,0x2C,0x27,0xF1,0xA9,0x62,0xC6,0xFC,0xB1,0x62,0xE7,
	0x60,0x2D,0x7F,0x00,0x00,0xFE,0xD6,0xAC,0xC6,0xC6,0xFC,0xE0,0x2E,0x2F,
	0xFE,0x27,0xF0,0x90,0x7A,0x01,0x00,0xCE,0xF0,0x1E };
unsigned char speed_put_8[68] = {
	0x27,0xF1,0xA9,0x62,0xC6,0xFC,0xB1,0x62,0xE7,0x60,0x28,0x27,0xF1,0xA9,
	0x62,0xC6,0xFC,0xB1,0x62,0xE7,0x60,0x29,0x27,0xF1,0xA9,0x62,0xC6,0xFC,
	0xB1,0x62,0xE7,0x60,0x2C,0x27,0xF1,0xA9,0x62,0xC6,0xFC,0xB1,0x62,0xE7,
	0x60,0x2D,0x7F,0x00,0x00,0xFE,0xD6,0x27,0xF1,0xA9,0x62,0xC6,0xFC,0xB1,
	0x62,0x27,0x60,0xE8,0x26,0x90,0x7A,0x01,0x00,0xCE,0xEE,0x1E };

unsigned get_entry(x) int x; { unsigned ent,z; z=(unsigned)x;
	ent=msb_data_get(entry_table)+msb_data_get(entry_table+1)*256;
	return(msb_data_get(ent+2*z)+msb_data_get(ent+2*z+1)*256); }
msb_data_put(add,data) unsigned add; int data; {
	set_command(0xe3); put_data(add/256); set_command(0xe5);
	put_data(add%256); set_command(0xeb); put_data(data); }
msb_data_get(add) unsigned add; {
	set_command(0xe3); put_data(add/256); set_command(0xe5);
	put_data(add%256); set_command(0xae); return(get_data()); }
msb_hot_reset(){ inp(DATAPT); inp(DATAPT); inp(DATAPT); set_command(0xff); }
put_command(x) int x; { while((inp(STATPT)&DRR)!=0){} outp(STATPT,x); }
put_data(x) int x; { while((inp(STATPT)&DRR)!=0){} outp(DATAPT,x); }
get_data(){ while((inp(STATPT)&DSR)!=0){} return(inp(DATAPT)); }
set_command(x) int x; { put_command(x); while(get_data()!=0xfe){} }
turbo_command_set(x,add,count) int x; unsigned add,count; {
	if(x==PUT) set_command(0xcd);
	else if(x==GET) set_command(0xcc);
	put_data(add/256); put_data(add%256);
	put_data(count/256); put_data(count%256); }

typedef struct _BP_NEURON {
	unsigned		count;
	double			out;
	struct _BP_NEURON	*next;
	struct _BP_NEURON	**link;
	double			*weight;
	double			*dw;
	double			delta;
} BP_NEURON;

BP_NEURON	input[INPUTUNIT];
BP_NEURON	hidden[HIDDENUNIT];
BP_NEURON	output[OUTPUTUNIT];
BP_NEURON	bias[BIASUNIT];

BpPropagate1(neuron) BP_NEURON *neuron;
{
	double net;
	net=Sigma(neuron); neuron->out=Sigmoid2(net);
}

BpPropagate(cluster) BP_NEURON *cluster;
{
	do{ BpPropagate1(cluster); }while(cluster=cluster->next);
}

BpInput(cluster,pattern) BP_NEURON *cluster; double *pattern;
{
	int i=0;
	do{ cluster->out=pattern[i++]; }while(cluster=cluster->next);
}

BpReset(cluster) BP_NEURON *cluster;
{
	BP_NEURON **n1; n1=&cluster;
	do{
		do{ cluster->delta=0.0; }while(cluster=cluster->next);
		n1=(BP_NEURON**)((int)n1+sizeof(BP_NEURON*));
		cluster=*n1;
	}while(cluster);
}

BpOutputLearning(n1,teacher) BP_NEURON *n1; double *teacher;
{
	int i=0; double tmp; BP_NEURON *n2; n2=n1;
	do{
		tmp=n2->out;
		n2->delta=(teacher[i++]-tmp)*tmp*(1-tmp);
	}while(n2=n2->next);
	do{
		for(i=0;icount;i++){
		    n1->link[i]->delta+=n1->delta*n1->weight[i];
		    n1->dw[i]=Eta*n1->delta*n1->link[i]->out+Alpha*n1->dw[i];
		    n1->weight[i]+=n1->dw[i];
		}
	}while(n1=n1->next);
}

BpHiddenLearning(n1) BP_NEURON *n1;
{
	int i; BP_NEURON *n2; n2=n1;
	do{ n2->delta*=n2->out*(1-n2->out); }while(n2=n2->next);
	do{
		for(i=0;icount;i++){
		    n1->link[i]->delta+=n1->delta*n1->weight[i];
		    n1->dw[i]=Eta*n1->delta*n1->link[i]->out+Alpha*n1->dw[i];
		    n1->weight[i]+=n1->dw[i];
		}
	}while(n1=n1->next);
}

nn_setting(){
	srand(3);
	Cluster1D(input,INPUTUNIT);
	Cluster1D(hidden,HIDDENUNIT);
	Cluster1D(output,OUTPUTUNIT);
	InitWeight(UNIFORM,0.5,-0.5);
	Connect(input,hidden);
	Connect(hidden,output);
	Connect(bias,hidden);
	Connect(bias,output);
	InitLinkAlloc(CONST,0.0,0.0);
	LinkAlloc1D(hidden,dw);
	LinkAlloc1D(output,dw);
	bias->out=1.0;
	strcpy(name,"hidden_"); strcat(name,number); strcat(name,".dat");
  	if((fds=fopen(name,"r"))==NULL){
		printf("\n\tHidden Weight File is not found.\n");
	}
	else{ WeightLoad( name, 0, hidden ); fclose(fds); }
	strcpy(name,"output_"); strcat(name,number); strcat(name,".dat");
  	if((fds=fopen(name,"r"))==NULL){
		printf("\n\tOutput Weight File is not found.\n");
	}
	else{ WeightLoad( name, 0, output ); fclose(fds); }
}

neuro_file_write(){
	strcpy(name,"output_"); strcat(name,number); strcat(name,".dat");
	WeightSave( name, "w", output );
	strcpy(name,"hidden_"); strcat(name,number); strcat(name,".dat");
	WeightSave( name, "w", hidden );
}

hex_data(){
	int i,j,k,ww;
	char name[32],nm[5];
	nm[1]=0;
	printf("\n\n\n\t! ! !  C A U T I O N  ! ! !");
	printf("\n\n\n\tWriting ROM Data file takes very long time!");
	printf("\n\n\n\t\t\t\tAre you OK ?   (y/n) --- ");
	while(1){ if(kbhit()){ if(getch()=='y') break; else return(0); } }
	for(i=0;i<8;i++){
		nm[0]=i+0x30;
		strcpy(name,"d-"); strcat(name,nm); strcat(name,".bin");
		fds=fopen(name,"wb"); printf("\n\nROM Bank = [%d]",i);
		for(j=0;j<4;j++){
			printf("\n\tWave = [%d]  ",j);
			for(ww=0;ww<32;ww++){
				putchar('.'); wave_calc(ww,4*i+j);
				for(k=0;k<512;k++) fputc(wb[k],fds);
			}
		}
		fclose(fds);
	}
}

intro_grain(){
	int i,j,d,xx,yy,yyy,x_max,dt,pt;
	_clearscreen(_GCLEARSCREEN); _setlinestyle(0x5555); _setcolor(7);
	_rectangle(_GBORDER,0,0,639,399);
	_settextposition(3,20); printf("Sample of Normal Sound Waveform");
	wave_calc(16,16,0); xx=30; yy=500; x_max=2300; _setlinestyle(0xffff);
	for(i=0;i512)&&(i<1024)) _lineto(xx+i/4,yyy);
		else _lineto(xx+i/4,pt);
	}
	mouse(1);
	while(1){ if(kbhit()){ d=getch(); if(d==0x1b) return; else break; } }
	mouse(0);
	_clearscreen(_GCLEARSCREEN); _setlinestyle(0x5555); _setcolor(7);
	_rectangle(_GBORDER,0,0,639,399);
	_settextposition(3,20); printf("Normal [ Smooth ] Grain");
	wave_calc(16,16,0); xx=50; yy=500; _setlinestyle(0xffff);
	_moveto(25,yy-7*128/5); _lineto(50,yy-7*128/5);
	for(i=0;i<512;i++){
		if(wb[i]<128) dt=wb[i]+128;
		else dt=128-(wb[i]&0x7f);
		yyy=yy-7*dt/5; _lineto(xx+i,yyy);
	}
	_lineto(615,yy-7*128/5);
	mouse(1);
	while(1){ if(kbhit()){ d=getch(); if(d==0x1b) return; else break; } }
	mouse(0);
	for(j=30;j>4;j=j-2){
		_clearscreen(_GCLEARSCREEN); _setlinestyle(0x5555);
		_rectangle(_GBORDER,0,0,639,399);
		_settextposition(3,15);
		printf("Waveshape Conversion of Grain : Parameter = %d",j);
		wave_calc(16,j,0); xx=50; yy=480; _setlinestyle(0xffff);
		_moveto(25,yy-7*128/5); _lineto(50,yy-7*128/5);
		for(i=0;i<512;i++){
			if(wb[i]<128) dt=wb[i]+128;
			else dt=128-(wb[i]&0x7f);
			yyy=yy-7*dt/5; _lineto(xx+i,yyy);
		}
		_lineto(615,yy-7*128/5);
		mouse(1);
		while(1){if(kbhit()){d=getch();if(d==0x1b)return;else break;}}
		mouse(0);
	}
	for(j=31;j>5;j=j-2){
		_clearscreen(_GCLEARSCREEN); _setlinestyle(0x5555);
		_rectangle(_GBORDER,0,0,639,399);
		_settextposition(3,15);
		printf("Waveshape Conversion of Grain : Parameter = %d",j);
		wave_calc(16,j,1); xx=50; yy=480; _setlinestyle(0xffff);
		_moveto(25,yy-7*128/5); _lineto(50,yy-7*128/5);
		for(i=0;i<512;i++){
			if(wb[i]<128) dt=wb[i]+128;
			else dt=128-(wb[i]&0x7f);
			yyy=yy-7*dt/5; _lineto(xx+i,yyy);
		}
		_lineto(615,yy-7*128/5);
		mouse(1);
		while(1){if(kbhit()){d=getch();if(d==0x1b)return;else break;}}
		mouse(0);
	}
	for(j=16;j>-1;j--){
		_clearscreen(_GCLEARSCREEN); _setlinestyle(0x5555);
		_rectangle(_GBORDER,0,0,639,399);
		_settextposition(3,15);
		printf("Waveshape Conversion of Grain : Parameter = %d",j);
		wave_calc(j,9,2); xx=50; yy=480; _setlinestyle(0xffff);
		_moveto(25,yy-7*128/5); _lineto(50,yy-7*128/5);
		for(i=0;i<512;i++){
			if(wb[i]<128) dt=wb[i]+128;
			else dt=128-(wb[i]&0x7f);
			yyy=yy-7*dt/5; _lineto(xx+i,yyy);
		}
		_lineto(615,yy-7*128/5);
		mouse(1);
		while(1){if(kbhit()){d=getch();if(d==0x1b)return;else break;}}
		mouse(0);
	}
	for(j=1;j<32;j++){
		_clearscreen(_GCLEARSCREEN); _setlinestyle(0x5555);
		_rectangle(_GBORDER,0,0,639,399);
		_settextposition(3,15);
		printf("Waveshape Conversion of Grain : Parameter = %d",j);
		wave_calc(j,9,2); xx=50; yy=480; _setlinestyle(0xffff);
		_moveto(25,yy-7*128/5); _lineto(50,yy-7*128/5);
		for(i=0;i<512;i++){
			if(wb[i]<128) dt=wb[i]+128;
			else dt=128-(wb[i]&0x7f);
			yyy=yy-7*dt/5; _lineto(xx+i,yyy);
		}
		_lineto(615,yy-7*128/5);
		mouse(1);
		while(1){if(kbhit()){d=getch();if(d==0x1b)return;else break;}}
		mouse(0);
	}
	for(j=30;j>15;j--){
		_clearscreen(_GCLEARSCREEN); _setlinestyle(0x5555);
		_rectangle(_GBORDER,0,0,639,399);
		_settextposition(3,15);
		printf("Waveshape Conversion of Grain : Parameter = %d",j);
		wave_calc(j,9,2); xx=50; yy=480; _setlinestyle(0xffff);
		_moveto(25,yy-7*128/5); _lineto(50,yy-7*128/5);
		for(i=0;i<512;i++){
			if(wb[i]<128) dt=wb[i]+128;
			else dt=128-(wb[i]&0x7f);
			yyy=yy-7*dt/5; _lineto(xx+i,yyy);
		}
		_lineto(615,yy-7*128/5);
		mouse(1);
		while(1){if(kbhit()){d=getch();if(d==0x1b)return;else break;}}
		mouse(0);
	}
}

wave_draw(z,mode)
	int z,mode;
{
	unsigned add;
	int i,j,xx,yy,xxx,yyy,tx,ty,dt,yyyy;
	xx=24+336*(z/8); xxx=xx+285; yy=9+48*(z%8); yyy=yy+43;
	_setcolor(0); _rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy); _setcolor(7);
	if(mode==0) _setlinestyle(0x9999);
	else if(mode==1) _setlinestyle(0xffff);
	xx=25+336*(z/8); xxx=xx+128; yy=10+48*(z%8); yyy=yy+42;
	_rectangle(_GBORDER,xx,yy,xxx,yyy);
	xx=157+336*(z/8); xxx=xx+145; yy=34+48*(z%8); yyy=yy+18;
	_rectangle(_GBORDER,xx,yy,xxx,yyy);
	ty=2+3*(z%8); tx=42*(z/8); _settextposition(ty,tx); printf("[%X]",z);
	_settextposition(ty-1,tx+20); printf(" KN=%02x  LE=%02x",kn[z],le[z]);
	xx=26+336*(z/8); xxx=xx+kn[z]; yy=13+48*(z%8); yyy=yy+4;
	_setlinestyle(0x5555); _rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy);
	xx=158+336*(z/8); xxx=xx+143*le[z]/127; yy=35+48*(z%8); yyy=yy+16;
	_setlinestyle(0x5555); _rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy);
	xx=25+336*(z/8); xxx=xx+128; yy=10+48*(z%8); yyy=yy+42;
	_setlinestyle(0xffff);
	for(i=0;i<512;i=i+4){
		if(i==0) _moveto(xx,yyy-14);
		else{
			if(wb[i]<128) dt=wb[i]+128;
			else dt=128-(wb[i]&0x7f);
			yyyy=yyy-56*dt/256+14;
			if(yyyy>yyy) yyyy=yyy;
			_lineto(xx+i/4,yyyy);
		}
		if (i==508) _lineto(xx+127,yyy-14);
	}
	if(mode==1) wave_sound(z);
}

wave_calc(ww,wk)
	int ww,wk;
{
	int i,wl,a,b;
	double p=3.1415926535,q,r,u,v=0;
	if(ww<16) wl=512-24*(16-ww);
	else wl=512-24*(ww-16);
	for(i=0;i<512;i++){
		if(i=0) wd[i]=(char)u;
		else wd[i]=(char)(128-u);
	}
	if(ww<16){
		a=(512-wl)/2; b=a+wl; for(i=0;i16){
		a=wl/2; b=a+(512-wl); for(i=0;i127-16) d=127-16;
	set_command(0xa9); put_data(d); put_data(kn[z]);
}

parameter_file_write(){
	int i;
	strcpy(name,"grain_"); strcat(name,number); strcat(name,".dat");
	fds=fopen(name,"wb");
	for(i=0;i<16;i++){ fputc(kn[i],fds); fputc(le[i],fds); }
	for(i=0;i<16;i++){ fputc(xp[i],fds); fputc(yp[i],fds); }
	fputc(ww,fds); fputc(wk,fds); fputc(wt,fds);
	fclose(fds);
}

parameter_file_read(){
	int i;
	strcpy(name,"grain_"); strcat(name,number); strcat(name,".dat");
	if((fds=fopen(name,"rb"))==NULL){
		for(i=0;i<16;i++){ kn[15-i]=32+i*4; le[15-i]=4+i*8; }
		for(i=0;i<16;i++){ xp[i]=8; yp[i]=8; }
		ww=16; wk=16; wt=0;
	}
	else{
		for(i=0;i<16;i++){ kn[i]=fgetc(fds); le[i]=fgetc(fds); }
		for(i=0;i<16;i++){ xp[i]=fgetc(fds); yp[i]=fgetc(fds); }
		ww=fgetc(fds); wk=fgetc(fds); wt=fgetc(fds);
		fclose(fds);
	}
}

mouse(flag) int flag; {
	if(flag==0){inregs.x.ax=2;} else if(flag==1){inregs.x.ax=1;}
	int86(51,&inregs,&outregs); }
getmouse(right,left,x,y) int *right,*left,*x,*y; {
	inregs.x.ax=3; int86(51,&inregs,&outregs); *right=outregs.x.bx;
	*left=outregs.x.ax; *x=outregs.x.cx; *y=outregs.x.dx; }
setmouse(x,y) int x,y; { inregs.x.ax=4; inregs.x.cx=x; inregs.x.dx=y;
	int86(51,&inregs,&outregs); }
m_style(x,y,buf) int x,y; char *buf; { inregs.x.ax=9; inregs.x.bx=x;
	inregs.x.cx=y; segread(&segregs); segregs.es=segregs.ds;
	inregs.x.dx=(int)buf; int86x(51,&inregs,&outregs,&segregs); }
m_view(xmin,ymin,xmax,ymax) int xmin,ymin,xmax,ymax; {
	inregs.x.ax=16; inregs.x.cx=xmin; inregs.x.dx=xmax;
	int86(51,&inregs,&outregs); inregs.x.ax=17; inregs.x.cx=ymin;
	inregs.x.dx=ymax; int86(51,&inregs,&outregs); }
m_color(color) int color; {
	inregs.x.ax=18; inregs.x.bx=color; int86(51,&inregs,&outregs); }
symbol(x,y,color,str,skip) int x,y,color,skip; unsigned char str[80]; {
	int i=0; _setcolor(color);
	while(str[i]!=0){ _gputchar(x,y,str[i++],_GXOR); x += skip; } }
static int style[]={
	0,0,0,0,0,0,0,0,0x0070,0x0e88,0x1184,0x2142,0x2221,0x9210,
	0xe107,0x1108,0x1108,0xe107,0x1108,0x1108,0xe107,0x4108,
	0x4208,0xfc07,0,0,0,0,0,0,0,0 };

main(argc,argv)
	int argc; char *argv[];
{
	int i,d;
	num=1; number[1]=0;
	number[0]='0'+num;
	inregs.x.ax=0; int86(51,&inregs,&outregs);
	if(outregs.x.ax==0){printf("\nPlease install mouse.sys !\n");exit(0);}
	m_style(0,8,style); m_color(1); m_view(0,0,639,399);
	msb_hot_reset(); wave_initialize_firmware_load();
	setmouse(320,200);
	parameter_file_read();
	_main_loop_top:
	mouse(0);
	printf("\x1b[2J\n\n\n\n\n");
	printf("      An Experiment of  ");
	printf("NEURO GRANULATION");
	printf("\n\n\n\n\t\t\tYOICHI NAGASHIMA");
	printf("\n\n\n\t\t\t\t\tSummer Symposium 1992 of JMACS\n\n");
	printf("\n\t\t(1) Introduction of Granular Synthesis");
	printf("\n\t\t(2) Select Sample Data File Group : [1]-[8]");
	printf("\n\t\t(3) Setting : Granulation Parameter --> Teacher");
	printf("\n\t\t(4) Mapping : Teacher Pattern --> Control Space");
	printf("\n\t\t(5) Learning : Neural Network Back Propagation");
	printf("\n\t\t(6) Running : Real-Time Neuro Granulation !");
	printf("\n\t\t(7) Writing Current Wave to HEX Data File");
	printf("\n\t\t\t\t\t\t\t\tselect : ");
	while(1){
		if(kbhit()){
			d=getch();
			if(d==0x1b){
				printf("\x1b[2J"); set_command(0xfe); exit(0);
			}
			else if((d>'0')&&(d<'8')){
				d=d-'0'; printf("\x1b[2J"); break;
			}
		}
	}
	switch(d){
		case 1: _setvideomode(_98RESS16COLOR);
			_displaycursor(_GCURSOROFF);
			intro_grain();
			_clearscreen(_GCLEARSCREEN);
			_displaycursor(_GCURSORON); break;
		case 2: file_group_change(); break;
		case 3: granulation_para(); break;
		case 4: teacher_mapping(); break;
		case 5: neural_net_learning(); break;
		case 6: sample_run(); break;
		case 7: hex_data(); break;
	}
	goto _main_loop_top;
}

file_group_change(){
	int d;
	printf("\x1b[2J\n\n\n\t\tSelect Sample Data File Group : [1]-[8]");
	printf("\n\n\n\t\t\tCurrent = %d",num);
	printf("\n\n\n\t\t\t\t\tselect [1-8] ----- ");
	while(1){
		if(kbhit()){
			d=getch();
			if(d==0x1b) return(0);
			else if((d>'0')&&(d<'9')){
				number[0]=d; num=d-'0';
				parameter_file_read(); break;
			}
		}
	}
}

neural_net_learning()
{
	int i,j,cnt=0,flg=0,err_count=30000;
	double dif,err,err_limit=0.005;
	long time1,time2;
	for(i=0;i<16;i++){
		pattern[i][0]=(double)xp[i]/17L;
		pattern[i][1]=(double)yp[i]/17L;
		teacher[i][0]=(double)kn[i]/127L;
		teacher[i][1]=(double)le[i]/127L;
	}
	printf("\n\nNeural Network Computation Start ...\n\n");
	nn_setting(); time(<ime); time1=ltime;
	do{
		for(err=0.0,i=0;i<16;i++){
			BpInput(input,pattern[i]);
			BpPropagate(hidden);
			BpPropagate(output);
			for(j=0;jerr_limit)&&(cnt++'){ /* Wave Width +1 */
			if(ww!=31){ flg=1; ww++; break; }
		}
		else if(c=='<'){ /* Wave Width -1 */
			if(ww!=0){ flg=1; ww--; break; }
		}
		else if(c=='+'){ /* Wave Type +1 */
			if(wk!=31){ flg=1; wk++; break; }
		}
		else if(c=='-'){ /* Wave Type -1 */
			if(wk!=0){ flg=1; wk--; break; }
		}
		else if((c=='d')||(c=='D')){ /* Wave : 2*sin */
			wt=0; flg=1; break;
		}
		else if((c=='t')||(c=='T')){ /* Wave : 3*sin */
			wt=1; flg=1; break;
		}
		else if((c=='q')||(c=='Q')){ /* Wave : 4*sin */
			wt=2; flg=1; break;
		}
	}
	if(flg!=0){ flg=0; goto _loop_loop; }
	parameter_file_write();
	mouse(0);
	_clearscreen(_GCLEARSCREEN); _displaycursor(_GCURSORON);
	set_command(0xa8);
}

mark_draw(p1,p2,pp,pt)
	int p1,p2,pp,pt;
{
	int i,j,xx,xxx,yy,yyy,fg=0;
	if(pp==99){
		xx=475; xxx=583; yy=79+16*p2; yyy=yy+18; _setlinestyle(0x5555);
		_setcolor(7); _rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy);
		xx=478; xxx=580; yy=79+16*p1; yyy=yy+18; _setlinestyle(0xffff);
		_setcolor(0); _rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy);
		return(0);
	}
	if(pp==1){
		xx=20+23*p1; xxx=xx+20; yy=5+23*(16-p2); yyy=yy+20;
		_setlinestyle(0xffff); _setcolor(7);
		_rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy); return(0);
	}
	xx=20+23*p1; xxx=xx+20; yy=5+23*(16-p2); yyy=yy+20; _setcolor(0);
	_setlinestyle(0xffff); _rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy);
	for(i=0;i<16;i++){ if((xp[i]==p1)&&(yp[i]==p2)) fg++; }
	_setcolor(7);
	if(pp==2){
		_setlinestyle(0x5555);
		if(fg==0) _rectangle(_GBORDER,xx,yy,xxx,yyy);
		else _rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy);
	}
	else if(pp==3){
		if((fg!=0)&&(p1==xp[pt])&&(p2==yp[pt])){
			_setlinestyle(0xffff);
			_rectangle(_GBORDER,xx,yy,xxx,yyy);
			_setlinestyle(0x6969);
			_rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy);
		}
		else if(fg!=0){
			_setlinestyle(0x5555);
			_rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy);
		}
		else{
			_setlinestyle(0x5555);
			_rectangle(_GBORDER,xx,yy,xxx,yyy);
		}
	}
}

teacher_mapping(){
	int i,j,c,d,xx,xxx,yy,yyy,rsb;
	int rsc=0,rsd=0,px=64,py=64,ox=64,oy=64,pt=15,ot=15;
	_setvideomode(_98RESS16COLOR); _setcolor(7);
	_displaycursor(_GCURSOROFF); _clearscreen(_GCLEARSCREEN);
	wave_calc(ww,wk); wave_set();
	for(i=0;i<17;i++){ for(j=0;j<17;j++) mark_draw(i,j,2,0); }
	_settextposition(2,57); printf("[[ WW=%d WK=%d ]]  ",ww,wk);
	_settextposition(23,59); printf("[[ Group = %d ]]  ",num);
	_setlinestyle(0x5555); _setcolor(7);
	xx=475; xxx=583; yy=69; yyy=91+16*16;
	_rectangle(_GFILLINTERIOR,xx,yy,xxx,yyy);
	for(i=0;i<16;i++){_settextposition(i+5,61); printf("Pattern <%X>",i);}
	mark_draw(pt,ot,99,0); wave_sound(pt);
	mark_draw(xp[pt],yp[pt],3,pt); mark_draw(8,8,1,0);
	while(1){
		while(!kbhit()){
			set_command(0xaa); d=get_data();
			if(d==0xcf){
				mouse(0);
				rsc=d; rsb=d; px=get_data();
				i=ox*100/753; j=oy*100/753;
				mark_draw(i,j,3,pt);
				i=px*100/753; j=py*100/753;
				mark_draw(i,j,1,0); ox=px;
				mouse(1);
			}
			else if(d==0xdf){
				mouse(0);
				rsd=d; rsb=d; py=get_data();
				i=ox*100/753; j=oy*100/753;
				mark_draw(i,j,3,pt);
				i=px*100/753; j=py*100/753;
				mark_draw(i,j,1,0); oy=py;
				mouse(1);
			}
		}
		c=getch();
		if(c==0x1b){ /* Escape */
			break;
		}
		else if(c==0x0b){ /* Up */
			mouse(0);
			pt=(pt+15)&0x0f; mark_draw(pt,ot,99,0);
			mark_draw(xp[ot],yp[ot],2,0);
			mark_draw(xp[pt],yp[pt],3,pt);
			wave_sound(pt); ot=pt;
			mouse(1);
		}
		else if(c==0x0a){ /* Down */
			mouse(0);
			pt=(pt+1)&0x0f; mark_draw(pt,ot,99);
			mark_draw(xp[ot],yp[ot],2,0);
			mark_draw(xp[pt],yp[pt],3,pt);
			wave_sound(pt); ot=pt;
			mouse(1);
		}
		else if(c==0x0d){ /* RETURN */
			mouse(0);
			i=xp[pt]; j=yp[pt];
			xp[pt]=px*100/753; yp[pt]=py*100/753;
			mark_draw(i,j,3,0);
			i=px*100/753; j=py*100/753;
			mark_draw(i,j,1,0);
			mouse(1);
		}
	}
	parameter_file_write();
	mouse(0);
	_clearscreen(_GCLEARSCREEN); _displaycursor(_GCURSORON);
	set_command(0xa8);
}

sample_run()
{
	int i,j,c,d,xx,xxx,yy,yyy;
	int px=64,py=64,opx=8,opy=8,rsb=0xcf;
	_setvideomode(_98RESS16COLOR); _setcolor(7);
	_displaycursor(_GCURSOROFF); _clearscreen(_GCLEARSCREEN);
	wave_calc(ww,wk); wave_set();
	for(i=0;i<17;i++){ for(j=0;j<17;j++) mark_draw(i,j,2,0); }
	_settextposition(3,54); printf("*** Real-Time Control ***");
	_settextposition(6,60); printf("WW=%d WK=%d ",ww,wk);
	_settextposition(16,59); printf("[[ Group = %d ]]  ",num);
	nn_setting(); mark_draw(8,8,1,0); nn_out(px,py,rsb);
	while(1){
		while(!kbhit()){
			set_command(0xaa); d=get_data();
			if(d==0xcf){
				rsb=d; px=get_data();
				i=px*100/753; j=py*100/753;
				if((opx!=i)||(opy!=j)){
					mark_draw(opx,opy,2,0);
					mark_draw(i,j,1,0);
					nn_out(px,py,rsb); opx=i; opy=j;
				}
			}
			else if(d==0xdf){
				rsb=d; py=get_data();
				i=px*100/753; j=py*100/753;
				if((opx!=i)||(opy!=j)){
					mark_draw(opx,opy,2,0);
					mark_draw(i,j,1,0);
					nn_out(px,py,rsb); opx=i; opy=j;
				}
			}
		}
		if(getch()==0x1b) break;
	}
	_clearscreen(_GCLEARSCREEN); _displaycursor(_GCURSORON);
	set_command(0xa8);
}

nn_out(px,py,rsb)
	int px,py,rsb;
{
	int i,j,k,l,d;
	double test[INPUTUNIT];
	test[0]=(double)px/127L; test[1]=(double)py/127L;
	BpInput(input,test); BpPropagate(hidden); BpPropagate(output);
	k=(int)(127.9L*output[0].out);
	_settextposition(10,60); printf("Key No. = %02X ",k);
	l=(int)(127.9L*output[1].out);
	_settextposition(12,60); printf("Loop End = %02X ",l);
	if(l>127-16) l=127-16;
	set_command(0xa9); put_data(l); put_data(k);
}