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

📄 common.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    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   common.c   */#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <time.h>#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif /* HAVE_SYS_TIME_H */#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif /* HAVE_SYS_TYPES_H */#ifdef HAVE_SYS_STAT_H#include <sys/stat.h>#endif /* HAVE_SYS_STAT_H */#include <fcntl.h>#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include <ctype.h>#ifndef __W32__#ifdef HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#else#include <process.h>#include <io.h>#endif /* __W32__ */#include "timidity.h"#include "common.h"#include "output.h"#include "controls.h"#include "arc.h"#include "nkflib.h"#include "wrd.h"#include "strtab.h"#include "support.h"/* RAND_MAX must defined in stdlib.h * Why RAND_MAX is not defined at SunOS? */#if defined(sun) && !defined(SOLARIS) && !defined(RAND_MAX)#define RAND_MAX ((1<<15)-1)#endif#ifndef O_BINARY#define O_BINARY 0#endif/* #define MIME_CONVERSION */char *program_name, current_filename[1024];MBlockList tmpbuffer;char *output_text_code = NULL;int open_file_noise_mode = OF_NORMAL;#ifdef DEFAULT_PATH    /* The paths in this list will be tried whenever we're reading a file */    static PathList defaultpathlist={DEFAULT_PATH,0};    static PathList *pathlist=&defaultpathlist; /* This is a linked list */#else    static PathList *pathlist=0;#endifconst char *note_name[] ={    "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};#ifndef TMP_MAX#define TMP_MAX 238328#endifinttmdy_mkstemp(char *tmpl){  char *XXXXXX;  static uint32 value;  uint32 random_time_bits;  int count, fd = -1;  int save_errno = errno;  /* These are the characters used in temporary filenames.  */  static const char letters[] =    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  /* This is where the Xs start.  */  XXXXXX = strstr(tmpl, "XXXXXX");  if (XXXXXX == NULL) {    errno = EINVAL;    return -1;  }  /* Get some more or less random data.  */#if HAVE_GETTIMEOFDAY  {    struct timeval tv;    gettimeofday(&tv, NULL);    random_time_bits = (uint32)((tv.tv_usec << 16) ^ tv.tv_sec);  }#else  random_time_bits = (uint32)time(NULL);#endif  value += random_time_bits ^ getpid();  for (count = 0; count < TMP_MAX; value += 7777, ++count) {    uint32 v = value;    /* Fill in the random bits.  */    XXXXXX[0] = letters[v % 62];    v /= 62;    XXXXXX[1] = letters[v % 62];    v /= 62;    XXXXXX[2] = letters[v % 62];    v = (v << 16) ^ value;    XXXXXX[3] = letters[v % 62];    v /= 62;    XXXXXX[4] = letters[v % 62];    v /= 62;    XXXXXX[5] = letters[v % 62];#if defined(_MSC_VER)#define S_IRUSR 0#define S_IWUSR 0#endif	fd = open(tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, S_IRUSR | S_IWUSR);    if (fd >= 0) {      errno = save_errno;      return fd;    }    if (errno != EEXIST)      return -1;  }  /* We got out of the loop because we ran out of combinations to try.  */  errno = EEXIST;  return -1;}static char *url_dumpfile(URL url, const char *ext){  char filename[1024];  char *tmpdir;  int fd;  FILE *fp;  int n;  char buff[BUFSIZ];#ifdef TMPDIR  tmpdir = TMPDIR;#else  tmpdir = getenv("TMPDIR");#endif  if(tmpdir == NULL || strlen(tmpdir) == 0)    tmpdir = PATH_STRING "tmp" PATH_STRING;  if(IS_PATH_SEP(tmpdir[strlen(tmpdir) - 1]))    snprintf(filename, sizeof(filename), "%sXXXXXX.%s", tmpdir, ext);  else    snprintf(filename, sizeof(filename), "%s" PATH_STRING "XXXXXX.%s",	     tmpdir, ext);  fd = tmdy_mkstemp(filename);  if (fd == -1)    return NULL;  if ((fp = fdopen(fd, "w")) == NULL) {    close(fd);    unlink(filename);    return NULL;  }  while((n = url_read(url, buff, sizeof(buff))) > 0)    fwrite(buff, 1, n, fp);  fclose(fp);  return safe_strdup(filename);}/* Try to open a file for reading. If the filename ends in one of the   defined compressor extensions, pipe the file through the decompressor */struct timidity_file *try_to_open(char *name, int decompress){    struct timidity_file *tf;    URL url;    int len;    if((url = url_arc_open(name)) == NULL)      if((url = url_open(name)) == NULL)	return NULL;    tf = (struct timidity_file *)safe_malloc(sizeof(struct timidity_file));    tf->url = url;    tf->tmpname = NULL;    len = strlen(name);    if(decompress && len >= 3 && strcasecmp(name + len - 3, ".gz") == 0)    {	int method;	if(!IS_URL_SEEK_SAFE(tf->url))	{	    if((tf->url = url_cache_open(tf->url, 1)) == NULL)	    {		close_file(tf);		return NULL;	    }	}	method = skip_gzip_header(tf->url);	if(method == ARCHIVEC_DEFLATED)	{	    url_cache_disable(tf->url);	    if((tf->url = url_inflate_open(tf->url, -1, 1)) == NULL)	    {		close_file(tf);		return NULL;	    }	    /* success */	    return tf;	}	/* fail */	url_rewind(tf->url);	url_cache_disable(tf->url);    }#ifdef __W32__    /* Sorry, DECOMPRESSOR_LIST and PATCH_CONVERTERS are not worked yet. */    return tf;#endif /* __W32__ */#if defined(DECOMPRESSOR_LIST)    if(decompress)    {	static char *decompressor_list[] = DECOMPRESSOR_LIST, **dec;	char tmp[1024];	/* Check if it's a compressed file */	for(dec = decompressor_list; *dec; dec += 2)	{	    if(!check_file_extension(name, *dec, 0))		continue;	    tf->tmpname = url_dumpfile(tf->url, *dec);	    if (tf->tmpname == NULL) {		close_file(tf);		return NULL;	    }	    url_close(tf->url);	    snprintf(tmp, sizeof(tmp), *(dec+1), tf->tmpname);	    if((tf->url = url_pipe_open(tmp)) == NULL)	    {		close_file(tf);		return NULL;	    }	    break;	}    }#endif /* DECOMPRESSOR_LIST */#if defined(PATCH_CONVERTERS)    if(decompress == 2)    {	static char *decompressor_list[] = PATCH_CONVERTERS, **dec;	char tmp[1024];	/* Check if it's a compressed file */	for(dec = decompressor_list; *dec; dec += 2)	{	    if(!check_file_extension(name, *dec, 0))		continue;	    tf->tmpname = url_dumpfile(tf->url, *dec);	    if (tf->tmpname == NULL) {		close_file(tf);		return NULL;	    }	    url_close(tf->url);	    sprintf(tmp, *(dec+1), tf->tmpname);	    if((tf->url = url_pipe_open(tmp)) == NULL)	    {		close_file(tf);		return NULL;	    }	    break;	}    }#endif /* PATCH_CONVERTERS */        return tf;}int is_url_prefix(const char *name){    int i;    static char *url_proto_names[] =    {	"file:",#ifdef SUPPORT_SOCKET	"http://",	"ftp://",	"news://",#endif /* SUPPORT_SOCKET */	"mime:",	NULL    };    for(i = 0; url_proto_names[i]; i++)	if(strncmp(name, url_proto_names[i], strlen(url_proto_names[i])) == 0)	    return 1;    return 0;}static int is_abs_path(const char *name){#ifndef __MACOS__	if (IS_PATH_SEP(name[0]))		return 1;#else	if (!IS_PATH_SEP(name[0]) && strchr(name, PATH_SEP) != NULL)		return 1;#endif /* __MACOS__ */#ifdef __W32__    /* [A-Za-z]: (for Windows) */    if (isalpha(name[0]) && name[1] == ':')		return 1;#endif /* __W32__ */	if (is_url_prefix(name))		return 1;	/* assuming relative notation is excluded */	return 0;}struct timidity_file *open_with_mem(char *mem, int32 memlen, int noise_mode){    URL url;    struct timidity_file *tf;    errno = 0;    if((url = url_mem_open(mem, memlen, 0)) == NULL)    {	if(noise_mode >= 2)	    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't open.");	return NULL;    }    tf = (struct timidity_file *)safe_malloc(sizeof(struct timidity_file));    tf->url = url;    tf->tmpname = NULL;    return tf;}/* This is meant to find and open files for reading, possibly piping   them through a decompressor. */struct timidity_file *open_file(char *name, int decompress, int noise_mode){  struct stat st;  struct timidity_file *tf;  PathList *plp=pathlist;  int l;  open_file_noise_mode = noise_mode;  if (!name || !(*name))    {      if(noise_mode)        ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Attempted to open nameless file.");      return 0;    }  /* First try the given name */  strncpy(current_filename, url_unexpand_home_dir(name), 1023);  current_filename[1023]='\0';  if(noise_mode)    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Trying to open %s", current_filename);  stat(current_filename, &st);  if(!S_ISDIR(st.st_mode))    if ((tf=try_to_open(current_filename, decompress)))      return tf;#ifdef __MACOS__  if(errno)#else  if(errno && errno != ENOENT)#endif    {	if(noise_mode)	    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",		      current_filename, strerror(errno));	return 0;    }  if (!is_abs_path(name))    while (plp)  /* Try along the path then */      {	*current_filename=0;	l=strlen(plp->path);	if(l)	  {              strncpy(current_filename, plp->path, sizeof(current_filename));	    if(!IS_PATH_SEP(current_filename[l-1]) &&	       current_filename[l-1] != '#' &&	       name[0] != '#')		strncat(current_filename, PATH_STRING, sizeof(current_filename) - strlen(current_filename) - 1);	  }	strncat(current_filename, name, sizeof(current_filename) - strlen(current_filename) - 1);	if(noise_mode)	    ctl->cmsg(CMSG_INFO, VERB_DEBUG,		      "Trying to open %s", current_filename);	stat(current_filename, &st);	if(!S_ISDIR(st.st_mode))	  if ((tf=try_to_open(current_filename, decompress)))	    return tf;#ifdef __MACOS__	if(errno)#else	if(errno && errno != ENOENT)#endif	{	    if(noise_mode)		ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",			  current_filename, strerror(errno));	    return 0;	  }	plp=plp->next;      }  /* Nothing could be opened. */  *current_filename=0;  if (noise_mode>=2)      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", name,		errno ? strerror(errno) : "Can't open file");  return 0;}/* This closes files opened with open_file */void close_file(struct timidity_file *tf){    int save_errno = errno;    if(tf->url != NULL)    {#ifndef __W32__	if(tf->tmpname != NULL)	{	    int i;	    /* dispose the pipe garbage */	    for(i = 0; tf_getc(tf) != EOF && i < 0xFFFF; i++)		;	}#endif /* __W32__ */	url_close(tf->url);    }    if(tf->tmpname != NULL)    {	unlink(tf->tmpname); /* remove temporary file */	free(tf->tmpname);    }    free(tf);    errno = save_errno;}/* This is meant for skipping a few bytes. */void skip(struct timidity_file *tf, size_t len){    url_skip(tf->url, (long)len);}char *tf_gets(char *buff, int n, struct timidity_file *tf){    return url_gets(tf->url, buff, n);}long tf_read(void *buff, int32 size, int32 nitems, struct timidity_file *tf){    return url_nread(tf->url, buff, size * nitems) / size;}long tf_seek(struct timidity_file *tf, long offset, int whence){    long prevpos;    prevpos = url_seek(tf->url, offset, whence);    if(prevpos == -1)	ctl->cmsg(CMSG_WARNING, VERB_NORMAL,		  "Warning: Can't seek file position");    return prevpos;}long tf_tell(struct timidity_file *tf){    long pos;    pos = url_tell(tf->url);    if(pos == -1)    {	ctl->cmsg(CMSG_WARNING, VERB_NORMAL,		  "Warning: Can't get current file position");	return (long)tf->url->nread;    }    return pos;}void safe_exit(int status){    if(play_mode->fd != -1)    {	play_mode->acntl(PM_REQ_DISCARD, NULL);	play_mode->close_output();    }    ctl->close();    wrdt->close();    exit(status);    /*NOTREACHED*/}/* This'll allocate memory or die. */void *safe_malloc(size_t count){    void *p;    static int errflag = 0;    if(errflag)	safe_exit(10);    if(count > MAX_SAFE_MALLOC_SIZE)    {	errflag = 1;	ctl->cmsg(CMSG_FATAL, VERB_NORMAL,		  "Strange, I feel like allocating %d bytes. "		  "This must be a bug.", count);    }    else {      if(count == 0)	/* Some malloc routine return NULL if count is zero, such as	 * malloc routine from libmalloc.a of Solaris.	 * But TiMidity doesn't want to return NULL even if count is zero.	 */	count = 1;      if((p = (void *)malloc(count)) != NULL)	return p;      errflag = 1;      ctl->cmsg(CMSG_FATAL, VERB_NORMAL,		"Sorry. Couldn't malloc %d bytes.", count);    }#ifdef ABORT_AT_FATAL    abort();#endif /* ABORT_AT_FATAL */    safe_exit(10);    /*NOTREACHED*/}void *safe_large_malloc(size_t count){    void *p;    static int errflag = 0;    if(errflag)	safe_exit(10);    if(count == 0)      /* Some malloc routine return NULL if count is zero, such as       * malloc routine from libmalloc.a of Solaris.       * But TiMidity doesn't want to return NULL even if count is zero.       */      count = 1;    if((p = (void *)malloc(count)) != NULL)      return p;    errflag = 1;    ctl->cmsg(CMSG_FATAL, VERB_NORMAL,	      "Sorry. Couldn't malloc %d bytes.", count);#ifdef ABORT_AT_FATAL    abort();#endif /* ABORT_AT_FATAL */    safe_exit(10);    /*NOTREACHED*/}void *safe_realloc(void *ptr, size_t count){    void *p;    static int errflag = 0;    if(errflag)	safe_exit(10);    if(count > MAX_SAFE_MALLOC_SIZE)    {	errflag = 1;	ctl->cmsg(CMSG_FATAL, VERB_NORMAL,		  "Strange, I feel like allocating %d bytes. "		  "This must be a bug.", count);    }    else {      if (ptr == NULL)	return safe_malloc(count);      if(count == 0)	/* Some malloc routine return NULL if count is zero, such as	 * malloc routine from libmalloc.a of Solaris.	 * But TiMidity doesn't want to return NULL even if count is zero.	 */	count = 1;      if((p = (void *)realloc(ptr, count)) != NULL)	return p;      errflag = 1;      ctl->cmsg(CMSG_FATAL, VERB_NORMAL,		"Sorry. Couldn't malloc %d bytes.", count);    }#ifdef ABORT_AT_FATAL    abort();#endif /* ABORT_AT_FATAL */    safe_exit(10);    /*NOTREACHED*/}/* This'll allocate memory or die. */

⌨️ 快捷键说明

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