⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tk_c.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 2 页
字号:
	/*k_pipe_puts("NEXT");*/	command = ctl_blocking_read(&val);	/* Main Loop */	for (;;)	{		if (command==RC_LOAD_FILE)		{			/* Read a LoadFile command */			k_pipe_gets(local, sizeof(local)-1);			command=play_midi_file(local);		}		else		{			if (command==RC_QUIT) {				/* if really QUIT */				k_pipe_gets(local, sizeof(local)-1);				if (*local == 'Z')					return;				/* only stop playing..*/			}			if (command==RC_CHANGE_VOLUME) /* init volume */				amplification += val;			switch(command)			{			case RC_ERROR:				k_pipe_puts("ERRR");				break;			case RC_NEXT:				k_pipe_puts("NEXT");				break;			case RC_REALLY_PREVIOUS:				k_pipe_puts("PREV");				break;			case RC_TUNE_END:				k_pipe_puts("TEND");				break;			case RC_RESTART:				k_pipe_puts("RSTA");				break;			}			command = ctl_blocking_read(&val);		}	}}/* open pipe and fork child process */static void k_pipe_open(void){	int res;	res = pipe(pipeAppli);	if (res!=0) k_pipe_error("PIPE_APPLI CREATION");	res = pipe(pipePanel);	if (res!=0) k_pipe_error("PIPE_PANEL CREATION");	if ((child_pid = fork()) == 0) {		/*child*/		close(pipePanel[1]);		close(pipeAppli[0]);		/* redirect to stdin/out */		dup2(pipePanel[0], fileno(stdin));		close(pipePanel[0]);		dup2(pipeAppli[1], fileno(stdout));		close(pipeAppli[1]);	} else {		close(pipePanel[0]);		close(pipeAppli[1]);		fpip_in= pipeAppli[0];		fpip_out= pipePanel[1];	}}#if defined(sgi)#include <sys/time.h>#endif#if defined(SOLARIS)#include <sys/filio.h>#endifstatic int k_pipe_read_ready(void){#if defined(sgi)    fd_set fds;    int cnt;    struct timeval timeout;    FD_ZERO(&fds);    FD_SET(fpip_in, &fds);    timeout.tv_sec = timeout.tv_usec = 0;    if((cnt = select(fpip_in + 1, &fds, NULL, NULL, &timeout)) < 0)    {	perror("select");	return -1;    }    return cnt > 0 && FD_ISSET(fpip_in, &fds) != 0;#else    int num;    if(ioctl(fpip_in,FIONREAD,&num) < 0) /* see how many chars in buffer. */    {	perror("ioctl: FIONREAD");	return -1;    }    return num;#endif}/***********************************************************************//* PIPE COMUNICATION                                                   *//***********************************************************************/static void k_pipe_error(char *st){    fprintf(stderr,"CONNECTION PROBLEM WITH TCL/TK PROCESS IN %s BECAUSE:%s\n",	    st,	    strerror(errno));    exit(1);}static void k_pipe_printf(char *fmt, ...){	char buf[256];	va_list ap;	va_start(ap, fmt);	vsnprintf(buf, sizeof(buf), fmt, ap);	k_pipe_puts(buf);}static int line_strlen(char *str){    int len;    len = 0;    while(*str && *str != '\r' && *str != '\n') {	str++;	len++;    }    return len;}static void k_pipe_puts(char *str){	int len;	char lf = '\n';	len = line_strlen(str);	write(fpip_out, str, len);	write(fpip_out, &lf, 1);}int k_pipe_gets(char *str, int maxlen){/* blocking reading */	char *p;	int len;	/* at least 5 letters (4+\n) command */	len = 0;	for (p = str; len < maxlen - 1; p++) {		read(fpip_in, p, 1);		if (*p == '\n')			break;		len++;	}	*p = 0;	return len;}/*---------------------------------------------------------------- * shared memory handling *----------------------------------------------------------------*//*ARGSUSED*/static void get_child(int sig){	child_killed = 1;}static void shm_alloc(void){	shmid = shmget(IPC_PRIVATE, sizeof(PanelInfo),		       IPC_CREAT|0600);	if (shmid < 0) {		fprintf(stderr, "can't allocate shared memory\n");		exit(1);	}	semid = semget(IPC_PRIVATE, 1, IPC_CREAT|0600);	if (semid < 0) {	    perror("semget");	    shmctl(shmid, IPC_RMID,NULL);	    exit(1);	}	/* bin semaphore: only call once at first */	semaphore_V(semid);	Panel = (PanelInfo *)shmat(shmid, 0, 0);	Panel->reset_panel = 0;	Panel->multi_part = 0;	Panel->wait_reset = 0;}static void shm_free(int sig){	int status;#if defined(HAVE_UNION_SEMUN)	union semun dmy;#else /* Solaris 2.x, BSDI, OSF/1, HPUX */	void *dmy;#endif	kill(child_pid, SIGTERM);	while(wait(&status) != child_pid)	    ;	memset(&dmy, 0, sizeof(dmy)); /* Shut compiler warning up :-) */	semctl(semid, 0, IPC_RMID, dmy);	shmctl(shmid, IPC_RMID, NULL);	shmdt((char *)Panel);	if (sig != 100)		exit(0);}/*---------------------------------------------------------------- * start Tk window panel *----------------------------------------------------------------*/static void start_panel(void){	char *argv[128];	int argc;	argc = 0;	argv[argc++] = "-f";	argv[argc++] = TKPROGPATH;	if (ctl.trace_playing) {		argv[argc++] = "-mode";		argv[argc++] = "trace";	}	/* call Tk main routine */	Tk_Main(argc, argv, AppInit);	exit(0);}/*---------------------------------------------------------------- * initialize Tcl application *----------------------------------------------------------------*/static Tcl_Interp *my_interp;static int AppInit(Tcl_Interp *interp){	my_interp = interp;	if (Tcl_Init(interp) == TCL_ERROR) {		return TCL_ERROR;	}	if (Tk_Init(interp) == TCL_ERROR) {		return TCL_ERROR;	}	Tcl_CreateCommand(interp, "TraceCreate", (Tcl_CmdProc*) TraceCreate,			  (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);	Tcl_CreateCommand(interp, "TraceUpdate", (Tcl_CmdProc*) TraceUpdate,			  (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);	Tcl_CreateCommand(interp, "TraceReset", (Tcl_CmdProc*) TraceReset,			  (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);	Tcl_CreateCommand(interp, "ExitAll", (Tcl_CmdProc*) ExitAll,			  (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);	Tcl_CreateCommand(interp, "TraceUpdate", (Tcl_CmdProc*) TraceUpdate,			  (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);	return TCL_OK;}/*ARGSUSED*/static int ExitAll(ClientData clientData, Tcl_Interp *interp,		   int argc, char *argv[]){	/* window is killed; kill the parent process, too */	kill(getppid(), SIGTERM);	for (;;)		sleep(1000);	return TCL_OK;}/* evaluate Tcl script */static char *v_eval(char *fmt, ...){	char buf[256];	va_list ap;	va_start(ap, fmt);	vsnprintf(buf, sizeof(buf), fmt, ap);	Tcl_Eval(my_interp, buf);	va_end(ap);	return my_interp->result;}static const char *v_get2(const char *v1, const char *v2){	return Tcl_GetVar2(my_interp, v1, v2, 0);}/*---------------------------------------------------------------- * update Tcl timer / trace window *----------------------------------------------------------------*/#define FRAME_WIN	".body.trace"#define CANVAS_WIN	FRAME_WIN ".c"#define BAR_WID 20#define BAR_HGT 130#define WIN_WID (BAR_WID * 16)#define WIN_HGT (BAR_HGT + 11 + 17)#define BAR_HALF_HGT (WIN_HGT / 2 - 11 - 17)/*ARGSUSED*/static int TraceCreate(ClientData clientData, Tcl_Interp *interp,		       int argc, char *argv[]){	int i;	v_eval("frame %s -bg black", FRAME_WIN);	v_eval("canvas %s -width %d -height %d -bd 0 -bg black "	       "-highlightthickness 0",	       CANVAS_WIN, WIN_WID, WIN_HGT);	v_eval("pack %s -side top -fill x", CANVAS_WIN);	for (i = 0; i < 32; i++) {		char *color;		v_eval("%s create text 0 0 -anchor n -fill white -text 00 "		       "-tags prog%d", CANVAS_WIN, i);		v_eval("%s create poly 0 0 0 0 0 0 -fill yellow -tags pos%d",		       CANVAS_WIN, i);		color = (ISDRUMCHANNEL(i) || i == 25) ? "red" : "green";		v_eval("%s create rect 0 0 0 0 -fill %s -tags bar%d "		       "-outline \"\"", CANVAS_WIN, color, i);	}	v_eval("set Stat(TimerId) -1");	v_eval("TraceReset");	return TCL_OK;}static void trace_bank(int ch, int val){	v_eval("%s itemconfigure bar%d -fill %s",	       CANVAS_WIN, ch,	       (val == 128 ? "red" : "green"));}static void trace_prog(int ch, int val){	v_eval("%s itemconfigure prog%d -text %02X",	       CANVAS_WIN, ch, val);}static void trace_sustain(int ch, int val){	v_eval("%s itemconfigure prog%d -fill %s",	       CANVAS_WIN, ch,	       (val == 127 ? "green" : "white"));}static void trace_prog_init(int ch){	int item, yofs, bar, x, y;	item = ch;	yofs = 0;	bar = Panel->multi_part ? BAR_HALF_HGT : BAR_HGT;	if (ch >= 16) {		ch -= 16;		yofs = WIN_HGT / 2;		if (!Panel->multi_part)			yofs = -500;	}	x = ch * BAR_WID + BAR_WID/2;	y = bar + 11 + yofs;	v_eval("%s coords prog%d %d %d", CANVAS_WIN, item, x, y);}static void trace_volume(int ch, int val){	int item, bar, yofs, x1, y1, x2, y2;	item = ch;	yofs = 0;	bar = Panel->multi_part ? BAR_HALF_HGT : BAR_HGT;	if (ch >= 16) {		yofs = WIN_HGT / 2;		ch -= 16;		if (!Panel->multi_part)			yofs = -500;	}	x1 = ch * BAR_WID;	y1 = bar - 1 + yofs;	x2 = x1 + BAR_WID - 1;	y2 = y1 - bar * val / 127;	v_eval("%s coords bar%d %d %d %d %d", CANVAS_WIN,	       item, x1, y1, x2, y2);}static void trace_panning(int ch, int val){	int item, bar, yofs;	int x, ap, bp;	if (val < 0) {		v_eval("%s coords pos%d -1 0 -1 0 -1 0", CANVAS_WIN, ch);		return;	}	item = ch;	yofs = 0;	bar = Panel->multi_part ? BAR_HALF_HGT : BAR_HGT;	if (ch >= 16) {		yofs = WIN_HGT / 2;		ch -= 16;		if (!Panel->multi_part)			yofs = -500;	}	x = BAR_WID * ch;	ap = BAR_WID * val / 127;	bp = BAR_WID - ap - 1;	v_eval("%s coords pos%d %d %d %d %d %d %d", CANVAS_WIN, item,	       ap + x, bar + 5 + yofs,	       bp + x, bar + 1 + yofs,	       bp + x, bar + 9 + yofs);}/*ARGSUSED*/static int TraceReset(ClientData clientData, Tcl_Interp *interp,			   int argc, char *argv[]){	int i;	semaphore_P(semid);	for (i = 0; i < 32; i++) {		trace_volume(i, 0);		trace_panning(i, -1);		trace_prog_init(i);		trace_prog(i, 0);		trace_sustain(i, 0);		Panel->ctotal[i] = 0;		Panel->cvel[i] = 0;		Panel->v_flags[i] = 0;		Panel->c_flags[i] = 0;	}	semaphore_V(semid);	Panel->wait_reset = 0;	return TCL_OK;}#define DELTA_VEL	32static void update_notes(void){	int i, imax;	semaphore_P(semid);	imax = Panel->multi_part ? 32 : 16;	for (i = 0; i < imax; i++) {		if (Panel->v_flags[i]) {			if (Panel->v_flags[i] == FLAG_NOTE_OFF) {				Panel->ctotal[i] -= DELTA_VEL;				if (Panel->ctotal[i] <= 0) {					Panel->ctotal[i] = 0;					Panel->v_flags[i] = 0;				}			} else {				Panel->v_flags[i] = 0;			}			trace_volume(i, Panel->ctotal[i]);		}		if (Panel->c_flags[i]) {			if (Panel->c_flags[i] & FLAG_PAN)				trace_panning(i, Panel->channel[i].panning);			if (Panel->c_flags[i] & FLAG_BANK)				trace_bank(i, Panel->channel[i].bank);			if (Panel->c_flags[i] & FLAG_PROG)				trace_prog(i, Panel->channel[i].program);			if (Panel->c_flags[i] & FLAG_SUST)				trace_sustain(i, Panel->channel[i].sustain);			Panel->c_flags[i] = 0;		}	}	semaphore_V(semid);}/*ARGSUSED*/static int TraceUpdate(ClientData clientData, Tcl_Interp *interp,		    int argc, char *argv[]){	const char *playing = v_get2("Stat", "Playing");	if (playing && *playing != '0') {		if (Panel->reset_panel) {			v_eval("TraceReset");			Panel->reset_panel = 0;		}		if (Panel->last_time != Panel->cur_time) {			v_eval("SetTime %d", Panel->cur_time);			Panel->last_time = Panel->cur_time;		}		if (ctl.trace_playing)			update_notes();	}	v_eval("set Stat(TimerId) [after 50 TraceUpdate]");	return TCL_OK;}static void ctl_event(CtlEvent *e){    switch(e->type)    {      case CTLE_NOW_LOADING:	ctl_file_name((char *)e->v1);	break;      case CTLE_LOADING_DONE:	break;      case CTLE_PLAY_START:	ctl_total_time((int)e->v1);	break;      case CTLE_PLAY_END:	break;      case CTLE_TEMPO:	break;      case CTLE_METRONOME:	break;      case CTLE_CURRENT_TIME:	ctl_current_time((int)e->v1, (int)e->v2);	break;      case CTLE_NOTE:	ctl_note((int)e->v1, (int)e->v2, (int)e->v3, (int)e->v4);	break;      case CTLE_MASTER_VOLUME:	ctl_master_volume((int)e->v1);	break;      case CTLE_PROGRAM:	ctl_program((int)e->v1, (int)e->v2);	break;      case CTLE_VOLUME:	ctl_volume((int)e->v1, (int)e->v2);	break;      case CTLE_EXPRESSION:	ctl_expression((int)e->v1, (int)e->v2);	break;      case CTLE_PANNING:	ctl_panning((int)e->v1, (int)e->v2);	break;      case CTLE_SUSTAIN:	ctl_sustain((int)e->v1, (int)e->v2);	break;      case CTLE_PITCH_BEND:	ctl_pitch_bend((int)e->v1, (int)e->v2);	break;      case CTLE_MOD_WHEEL:	ctl_pitch_bend((int)e->v1, e->v2 ? -1 : 0x2000);	break;      case CTLE_CHORUS_EFFECT:	break;      case CTLE_REVERB_EFFECT:	break;      case CTLE_LYRIC:	ctl_lyric((int)e->v1);	break;      case CTLE_REFRESH:	ctl_refresh();	break;      case CTLE_RESET:	ctl_reset();	break;    }}/* * interface_<id>_loader(); */ControlMode *interface_k_loader(void){    return &ctl;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -