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

📄 wrd_read.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    TiMidity++ -- MIDI to WAVE converter and player    Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    WRD reader - Written by Masanao Izumo <mo@goice.co.jp>		 Modified by Takaya Nogami <t-nogami@happy.email.ne.jp> for			Sherry WRD. */#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#include <stdlib.h>#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include <ctype.h>#include "timidity.h"#include "common.h"#include "instrum.h"#include "playmidi.h"#include "readmidi.h"#include "controls.h"#include "wrd.h"#include "strtab.h"/*#define DEBUG 1*/#if  defined(JAPANESE) || defined(__MACOS__)#define IS_MULTI_BYTE(c)	( ((c)&0x80) && ((0x1 <= ((c)&0x7F) && ((c)&0x7F) <= 0x1f) ||\				 (0x60 <= ((c)&0x7F) && ((c)&0x7F) <= 0x7c)))#define IS_SJIS_ZENKAKU_SPACE(p) ((p)[0] == 0x81 && (p)[1] == 0x40)#else#define IS_MULTI_BYTE(c)	0#endif /* JAPANESE */#define WRDENDCHAR 26 /* ^Z */#define MAXTOKLEN 255#define MAXTIMESIG 256/* * Define Bug emulation level. * 0: No emulatoin. * 1: Standard emulation (emulate if the bugs is well known). * 2: More emulation (including unknown bugs). * 3-9: Danger level!! (special debug level) */#ifndef MIMPI_BUG_EMULATION_LEVEL#define MIMPI_BUG_EMULATION_LEVEL 1#endifstatic int mimpi_bug_emulation_level = MIMPI_BUG_EMULATION_LEVEL;static int wrd_bugstatus;static int wrd_wmode_prev_step;#ifdef DEBUG#define WRD_BUGEMUINFO(code) ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, \    "WRD: Try to emulate bug of MIMPI at line %d (code=%d)", lineno, code)#else#define WRD_BUGEMUINFO(code) ctl->cmsg(CMSG_WARNING, VERB_NOISY, \    "WRD: Try to emulate bug of MIMPI at line %d", lineno)#endif /* DEBUG *//* Current max code: 13 */#define FADE_SPEED_BASE 24 /* 24 or 48?? */StringTable wrd_read_opts;static int version;struct wrd_delayed_event{    int32 waittime;    int cmd, arg;    struct wrd_delayed_event* next;};struct wrd_step_tracer{    int32 at;		/* total step count */    int32 last_at;	/* estimated maxmum steps */    int32 step_inc;	/* increment steps per newline or character */    int bar;		/* total bar count */    int step;		/* step in current bar */    int barstep;	/* step count of current bar */    MidiEvent timesig[MAXTIMESIG]; /* list of time signature code */    int timeidx;	/* index of current timesig */    int ntimesig;	/* number of time signatures */    int timebase;	/* divisions */    int offset;		/* @OFFSET */    int wmode0, wmode1;	/* @WMODE */    /* Delayed MIDI event list */    struct wrd_delayed_event *de;    struct wrd_delayed_event *free_de;    MBlockList pool;	/* memory buffer */};static MBlockList sry_pool; /* data buffer */sry_datapacket *datapacket = NULL;#ifdef ENABLE_SHERRYstatic int datapacket_len, datapacket_cnt;#define DEFAULT_DATAPACKET_LEN 16384static int import_sherrywrd_file(const char * );#endif /* ENABLE_SHERRY */static uint8 cmdlookup(uint8 *cmd);static int wrd_nexttok(struct timidity_file *tf);static void wrd_readinit(void);static struct timidity_file *open_wrd_file(char *fn);static int wrd_hexval(char *hex);static int wrd_eint(char *hex);static int wrd_atoi(char *val, int default_value);static void wrd_add_lyric(int32 at, char *lyric, int len);static int wrd_split(char* arg, char** argv, int maxarg);static void wrdstep_inc(struct wrd_step_tracer *wrdstep, int32 inc);static void wrdstep_update_forward(struct wrd_step_tracer *wrdstep);static void wrdstep_update_backward(struct wrd_step_tracer *wrdstep);static void wrdstep_nextbar(struct wrd_step_tracer *wrdstep);static void wrdstep_prevbar(struct wrd_step_tracer *wrdstep);static void wrdstep_wait(struct wrd_step_tracer *wrdstep, int bar, int step);static void wrdstep_rest(struct wrd_step_tracer *wrdstep, int bar, int step);static struct wrd_delayed_event *wrd_delay_cmd(struct wrd_step_tracer *wrdstep,					int32 waittime, int cmd, int arg);static uint8 wrd_tokval[MAXTOKLEN + 1]; /* Token value */static uint8 wrd_tok;		/* Token type */static int lineno;		/* linenumber */static int32 last_event_time;#define WRD_ADDEVENT(at, cmd, arg) \    { MidiEvent e; e.time = (at); e.type = ME_WRD; e.channel = (cmd); \      e.a = (uint8)((arg) & 0xFF); e.b = (uint8)(((arg) >> 8) & 0xFF); \      if(mimpi_bug_emulation_level > 0){ if(at < last_event_time){ e.time = \      last_event_time; }else{ last_event_time = e.time; }} \      readmidi_add_event(&e); }#define WRD_ADDSTREVENT(at, cmd, str) \    { MidiEvent e; readmidi_make_string_event(ME_WRD, (str), &e, 0); \      e.channel = (cmd); e.time = (at); \      if(mimpi_bug_emulation_level > 0){ if(at < last_event_time){ e.time = \      last_event_time; }else{ last_event_time = e.time; }} \      readmidi_add_event(&e); }#define SETMIDIEVENT(e, at, t, ch, pa, pb) \    { (e).time = (at); (e).type = (t); \      (e).channel = (uint8)(ch); (e).a = (uint8)(pa); (e).b = (uint8)(pb); }#define MIDIEVENT(at, t, ch, pa, pb) \    { MidiEvent event; SETMIDIEVENT(event, at, t, ch, pa, pb); \      readmidi_add_event(&event); }#ifdef DEBUGstatic char *wrd_name_string(int cmd);#endif /* DEBUG */int import_wrd_file(char *fn){    struct timidity_file *tf;    char *args[WRD_MAXPARAM], *arg0;    int argc;    int32 i, num;    struct wrd_step_tracer wrdstep;#define step_at wrdstep.at    static int initflag = 0;    static char *default_wrd_file1, /* Default */		*default_wrd_file2; /* Always */    char *wfn; /* opened WRD filename */    StringTableNode *stn; /* Chain list of string */    if(!initflag) /* Initialize at once */    {	char *read_opts[WRD_MAXPARAM];	initflag = 1;	for(stn = wrd_read_opts.head; stn; stn = stn->next)	{	    int nopts;	    nopts = wrd_split(stn->string, read_opts, WRD_MAXPARAM);	    for(i = 0; i < nopts; i++)	    {		char *a, *b;		a = read_opts[i];		if((b = strchr(a, '=')) != NULL)		    *b++ = '\0';		if(strcmp(a, "d") == 0)		    mimpi_bug_emulation_level = (b ? atoi(b) : 0);		else if(strcmp(a, "f") == 0)		{		    if(default_wrd_file1 != NULL)			free(default_wrd_file1);		    default_wrd_file1 = (b ? safe_strdup(b) : NULL);		}		else if(strcmp(a, "F") == 0)		{		    if(default_wrd_file2 != NULL)			free(default_wrd_file2);		    default_wrd_file2 = (b ? safe_strdup(b) : NULL);		}		else if(strcmp(a, "p") == 0)		{		    if(b != NULL)			wrd_add_default_path(b);		}	    }	}    }    if(datapacket == NULL)	init_mblock(&sry_pool);    else    {	free(datapacket);	datapacket = NULL;	reuse_mblock(&sry_pool);    }    wrd_init_path();    if(default_wrd_file2 != NULL)	tf = open_file((wfn = default_wrd_file2), 0, OF_NORMAL);    else	tf = open_wrd_file(wfn = fn);    if(tf == NULL && default_wrd_file1 != NULL)	tf = open_file((wfn = default_wrd_file1), 0, OF_NORMAL);    if(tf == NULL)    {	default_wrd_file1 = default_wrd_file2 = NULL;#ifdef ENABLE_SHERRY	if(import_sherrywrd_file(fn))	    return WRD_TRACE_SHERRY;#endif	return WRD_TRACE_NOTHING;    }    wrd_readinit();    memset(&wrdstep, 0, sizeof(wrdstep));    init_mblock(&wrdstep.pool);    wrdstep.de = wrdstep.free_de = NULL;    wrdstep.timebase = current_file_info->divisions;    wrdstep.ntimesig = dump_current_timesig(wrdstep.timesig, MAXTIMESIG - 1);    if(wrdstep.ntimesig > 0)    {	wrdstep.timesig[wrdstep.ntimesig] =	    wrdstep.timesig[wrdstep.ntimesig - 1];	wrdstep.timesig[wrdstep.ntimesig].time = 0x7fffffff; /* stopper */#ifdef DEBUG	printf("Time signatures:\n");	for(i = 0; i < wrdstep.ntimesig; i++)	    printf("  %d: %d/%d\n",		   wrdstep.timesig[i].time,		   wrdstep.timesig[i].a,		   wrdstep.timesig[i].b);#endif /* DEBUG */	wrdstep.barstep =	    wrdstep.timesig[0].a * wrdstep.timebase * 4 / wrdstep.timesig[0].b;    }    else	wrdstep.barstep = 4 * wrdstep.timebase;    wrdstep.step_inc = wrdstep.barstep;    wrdstep.last_at = readmidi_set_track(0, 0);    readmidi_set_track(0, 1);#ifdef DEBUG    printf("Timebase: %d\n", wrdstep.timebase);    printf("Step: %d\n", wrdstep.step_inc);#endif /* DEBUG */    while(!readmidi_error_flag && wrd_nexttok(tf))    {	if(version == -1 &&	   (wrd_tok != WRD_COMMAND || wrd_tokval[0] != WRD_STARTUP))	{	    /* WRD_STARTUP must be first */	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "WRD: No @STARTUP");	    version = 0;	    WRD_ADDEVENT(0, WRD_STARTUP, 0);	}#ifdef DEBUG	printf("%d: [%d,%d]/%d %s: ",	       lineno,	       wrdstep.bar,	       wrdstep.step,	       wrd_bugstatus,	       wrd_name_string(wrd_tok));	if(wrd_tok == WRD_COMMAND)	    printf("%s(%s)", wrd_name_string(wrd_tokval[0]), wrd_tokval + 1);	else if(wrd_tok == WRD_LYRIC)	    printf("<%s>", wrd_tokval);	printf("\n");	fflush(stdout);#endif /* DEBUG */	switch(wrd_tok)	{	  case WRD_COMMAND:	    arg0 = (char *)wrd_tokval + 1;	    switch(wrd_tokval[0])	    {	      case WRD_COLOR:		num = atoi(arg0);		WRD_ADDEVENT(step_at, WRD_COLOR, num);		break;	      case WRD_END:		while(step_at < wrdstep.last_at)		    wrdstep_nextbar(&wrdstep);		break;	      case WRD_ESC:		WRD_ADDSTREVENT(step_at, WRD_ESC, arg0);		break;	      case WRD_EXEC:		WRD_ADDSTREVENT(step_at, WRD_EXEC, arg0);		break;	      case WRD_FADE:		argc = wrd_split(arg0, args, 3);		for(i = 0; i < 2; i++)		{		    num = atoi(args[i]);		    WRD_ADDEVENT(step_at, WRD_ARG, num);		}		num = wrd_atoi(args[i], 1);		WRD_ADDEVENT(step_at, WRD_FADE, num);		if(num >= 1)		{		    int32 delay, fade_speed;		    fade_speed = (num + 1) * wrdstep.timebase / FADE_SPEED_BASE;		    for(i = 1; i < WRD_MAXFADESTEP; i++)		    {			delay =	(int32)((double)fade_speed *				       i / WRD_MAXFADESTEP);			wrd_delay_cmd(&wrdstep, delay, WRD_ARG,				      i);			wrd_delay_cmd(&wrdstep, delay, WRD_FADESTEP,				      WRD_MAXFADESTEP);		    }		    wrd_delay_cmd(&wrdstep, fade_speed, WRD_ARG,				  WRD_MAXFADESTEP);		    wrd_delay_cmd(&wrdstep, fade_speed, WRD_FADESTEP,				  WRD_MAXFADESTEP);		}		break;	      case WRD_GCIRCLE:		argc = wrd_split(arg0, args, 6);		if(argc < 5)		{		    /* Error : Too few argument */		    break;		}		for(i = 0; i < 5; i++)		{		    num = atoi(args[i]);		    WRD_ADDEVENT(step_at, WRD_ARG, num);		}		num = atoi(args[i]);		WRD_ADDEVENT(step_at, WRD_GCIRCLE, num);		break;	      case WRD_GCLS:		num = atoi(arg0);		WRD_ADDEVENT(step_at, WRD_GCLS, num);		break;	      case WRD_GINIT:		WRD_ADDEVENT(step_at, WRD_GINIT, 0);		break;	      case WRD_GLINE:		argc = wrd_split(arg0, args, 7);		if(argc < 4)		{		    /* Error: Too few arguments */		    break;		}		for(i = 0; i < 4; i++)		{		    num = atoi(args[i]);		    WRD_ADDEVENT(step_at, WRD_ARG, num)		}		WRD_ADDEVENT(step_at, WRD_ARG,   atoi(args[4]));		WRD_ADDEVENT(step_at, WRD_ARG,   atoi(args[5]));		WRD_ADDEVENT(step_at, WRD_GLINE, atoi(args[6]));		break;	      case WRD_GMODE:		num = atoi(arg0);		WRD_ADDEVENT(step_at, WRD_GMODE, num)		break;	      case WRD_GMOVE:		argc = wrd_split(arg0, args, 9);		if(argc < 6)		{		    /* Error: Too few arguments */		    break;		}		for(i = 0; i < 8; i++)		{		    num = atoi(args[i]);		    WRD_ADDEVENT(step_at, WRD_ARG, num);		}		num = atoi(args[i]);		WRD_ADDEVENT(step_at, WRD_GMOVE, num)		break;	      case WRD_GON:		num = atoi(arg0);		WRD_ADDEVENT(step_at, WRD_GON, num);		break;	      case WRD_GSCREEN:		if(mimpi_bug_emulation_level >= 1)		{		    for(i = 0; arg0[i]; i++)			if(arg0[i] == '.')			{			    WRD_BUGEMUINFO(110);			    arg0[i] = ',';			}		}		argc = wrd_split(arg0, args, 2);		if(argc != 2)		{		    /* Error: Number of arguments miss match */		    break;		}		num = atoi(args[0]);		WRD_ADDEVENT(step_at, WRD_ARG, num);		num = atoi(args[1]);		WRD_ADDEVENT(step_at, WRD_GSCREEN, num);		break;	      case WRD_INKEY: /* FIXME */		num = atoi(arg0);		if(num < wrdstep.bar)		{		    /* Error */		    break;		}		WRD_ADDEVENT(step_at, WRD_INKEY, WRD_NOARG);		num = (num - wrdstep.bar) * wrdstep.barstep;		wrd_delay_cmd(&wrdstep, num, WRD_OUTKEY, WRD_NOARG);		break;	      case WRD_LOCATE:		if(strchr(arg0, ';') != NULL)		    i = 1; /* Swap argument */		else		    i = 0;		argc = wrd_split(arg0, args, 2);		if(argc != 2)		{		    /* Error: Number of arguments miss match */		    break;		}		if(i)		{		    num = atoi(args[1]);		    WRD_ADDEVENT(step_at, WRD_ARG, num);		    num = atoi(args[0]);		    WRD_ADDEVENT(step_at, WRD_LOCATE, num);		}		else		{		    num = atoi(args[0]);		    WRD_ADDEVENT(step_at, WRD_ARG, num);		    num = atoi(args[1]);		    WRD_ADDEVENT(step_at, WRD_LOCATE, num);		}		break;	      case WRD_LOOP: /* Not supported */		break;	      case WRD_MAG:		argc = wrd_split(arg0, args, 5);		if(!*args[0])		{		    /* Error: @MAG No file name */		    break;		}		WRD_ADDSTREVENT(step_at, WRD_ARG, args[0]);		for(i = 1; i < 3; i++)		    WRD_ADDEVENT(step_at, WRD_ARG,				 wrd_atoi(args[i], WRD_NOARG));		WRD_ADDEVENT(step_at, WRD_ARG, wrd_atoi(args[3], 1));		WRD_ADDEVENT(step_at, WRD_MAG, atoi(args[4]));		break;	      case WRD_MIDI:		argc = wrd_split(arg0, args, WRD_MAXPARAM);		for(i = 0; i < argc; i++)		    WRD_ADDEVENT(step_at, WRD_ARG, wrd_hexval(args[i]));		WRD_ADDEVENT(step_at, WRD_MIDI, atoi(args[i]));		break;	      case WRD_OFFSET:		wrdstep.offset = atoi(arg0);		break;	      case WRD_PAL:		argc = wrd_split(arg0, args, 17);		if(argc != 16 && argc != 17)		{		    /* Error: Number of arguments miss match */		    break;		}		if(argc == 16)		{		    WRD_ADDEVENT(step_at, WRD_ARG, 0);		    i = 0;		}		else		{		    if(*args[0] == '#')			num = atoi(args[0] + 1);		    else			num = atoi(args[0]);		    WRD_ADDEVENT(step_at, WRD_ARG, num);		    i = 1;		}		for(; i < argc - 1; i++)

⌨️ 快捷键说明

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