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

📄 sffile.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*//*================================================================ * sffile.c *	read SoundFont file (SBK/SF2) and store the layer lists * * Copyright (C) 1996,1997 Takashi Iwai * * 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 *================================================================*//* * Modified by Masanao Izumo <mo@goice.co.jp> */#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include <stdlib.h>#include "timidity.h"#include "common.h"#include "controls.h"#include "sffile.h"extern int progbase;/*================================================================ * preset / instrument bag record *================================================================*/typedef struct _SFBags {	int nbags;	uint16 *bag;	int ngens;	SFGenRec *gen;} SFBags;static SFBags prbags, inbags;/*---------------------------------------------------------------- * function prototypes *----------------------------------------------------------------*/#define NEW(type,nums)	(type*)safe_malloc(sizeof(type) * (nums))static int READCHUNK(SFChunk *vp, struct timidity_file *tf){    if(tf_read(vp, 8, 1, tf) != 1)	return -1;    vp->size = LE_LONG(vp->size);    return 1;}static int READDW(uint32 *vp, struct timidity_file *tf){    if(tf_read(vp, 4, 1, tf) != 1)	return -1;    *vp = LE_LONG(*vp);    return 1;}static int READW(uint16 *vp, struct timidity_file *tf){    if(tf_read(vp, 2, 1, tf) != 1)	return -1;    *vp = LE_SHORT(*vp);    return 1;}static int READSTR(char *str, struct timidity_file *tf){    int n;    if(tf_read(str, 20, 1, tf) != 1)	return -1;    str[19] = '\0';    n = strlen(str);    while(n > 0 && str[n - 1] == ' ')	n--;    str[n] = '\0';    return n;}#define READID(var,tf)	tf_read(var, 4, 1, tf)#define READB(var,tf)	tf_read(&var, 1, 1, tf)#define SKIPB(tf)	skip(tf, 1)#define SKIPW(tf)	skip(tf, 2)#define SKIPDW(tf)	skip(tf, 4)#define FSKIP(size,tf)	skip(tf, size)/*----------------------------------------------------------------*/static int chunkid(char *id);static int process_list(int size, SFInfo *sf, struct timidity_file *fd);static int process_info(int size, SFInfo *sf, struct timidity_file *fd);static int process_sdta(int size, SFInfo *sf, struct timidity_file *fd);static int process_pdta(int size, SFInfo *sf, struct timidity_file *fd);static void load_sample_names(int size, SFInfo *sf, struct timidity_file *fd);static void load_preset_header(int size, SFInfo *sf, struct timidity_file *fd);static void load_inst_header(int size, SFInfo *sf, struct timidity_file *fd);static void load_bag(int size, SFBags *bagp, struct timidity_file *fd);static void load_gen(int size, SFBags *bagp, struct timidity_file *fd);static void load_sample_info(int size, SFInfo *sf, struct timidity_file *fd);static void convert_layers(SFInfo *sf);static void generate_layers(SFHeader *hdr, SFHeader *next, SFBags *bags);static void free_layer(SFHeader *hdr);/*---------------------------------------------------------------- * id numbers *----------------------------------------------------------------*/enum {	/* level 0; chunk */	UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID,	/* level 1; id only */	INFO_ID, SDTA_ID, PDTA_ID,	/* info stuff; chunk */	IFIL_ID, ISNG_ID, IROM_ID, INAM_ID, IVER_ID, IPRD_ID, ICOP_ID,	ICRD_ID, IENG_ID, ISFT_ID, ICMT_ID,	/* sample data stuff; chunk */	SNAM_ID, SMPL_ID,	/* preset stuff; chunk */	PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID,	/* inst stuff; chunk */	INST_ID, IBAG_ID, IMOD_ID, IGEN_ID,	/* sample header; chunk */	SHDR_ID};/*================================================================ * load a soundfont file *================================================================*/int load_soundfont(SFInfo *sf, struct timidity_file *fd){	SFChunk chunk;	sf->preset = NULL;	sf->sample = NULL;	sf->inst = NULL;	sf->sf_name = NULL;	prbags.bag = inbags.bag = NULL;	prbags.gen = inbags.gen = NULL;	/* check RIFF file header */	READCHUNK(&chunk, fd);	if (chunkid(chunk.id) != RIFF_ID) {		ctl->cmsg(CMSG_ERROR, VERB_NORMAL,			  "%s: *** not a RIFF file", current_filename);		return -1;	}	/* check file id */	READID(chunk.id, fd);	if (chunkid(chunk.id) != SFBK_ID) {		ctl->cmsg(CMSG_ERROR, VERB_NORMAL,			  "%s: *** not a SoundFont file", current_filename);		return -1;	}	for (;;) {		if(READCHUNK(&chunk, fd) <= 0)			break;		else if (chunkid(chunk.id) == LIST_ID) {			if (process_list(chunk.size, sf, fd))				break;		} else {			ctl->cmsg(CMSG_WARNING, VERB_NORMAL,				  "%s: *** illegal id in level 0: %4.4s %4d",				  current_filename, chunk.id, chunk.size);			FSKIP(chunk.size, fd);		}	}	/* parse layer structure */	convert_layers(sf);	/* free private tables */	if (prbags.bag) free(prbags.bag);	if (prbags.gen) free(prbags.gen);	if (inbags.bag) free(inbags.bag);	if (inbags.gen) free(inbags.gen);	return 0;}/*================================================================ * free buffer *================================================================*/void free_soundfont(SFInfo *sf){	int i;	if (sf->preset) {		for (i = 0; i < sf->npresets; i++)			free_layer(&sf->preset[i].hdr);		free(sf->preset);	}	if (sf->inst) {		for (i = 0; i < sf->ninsts; i++)			free_layer(&sf->inst[i].hdr);		free(sf->inst);	}	if (sf->sample) free(sf->sample);	if (sf->sf_name) free(sf->sf_name);}/*---------------------------------------------------------------- * get id value from 4bytes ID string *----------------------------------------------------------------*/static int chunkid(char *id){	static struct idstring {		char *str;		int id;	} idlist[] = {		{"RIFF", RIFF_ID},		{"LIST", LIST_ID},		{"sfbk", SFBK_ID},		{"INFO", INFO_ID},		{"sdta", SDTA_ID},		{"snam", SNAM_ID},		{"smpl", SMPL_ID},		{"pdta", PDTA_ID},		{"phdr", PHDR_ID},		{"pbag", PBAG_ID},		{"pmod", PMOD_ID},		{"pgen", PGEN_ID},		{"inst", INST_ID},		{"ibag", IBAG_ID},		{"imod", IMOD_ID},		{"igen", IGEN_ID},		{"shdr", SHDR_ID},		{"ifil", IFIL_ID},		{"isng", ISNG_ID},		{"irom", IROM_ID},		{"iver", IVER_ID},		{"INAM", INAM_ID},		{"IPRD", IPRD_ID},		{"ICOP", ICOP_ID},		{"ICRD", ICRD_ID},		{"IENG", IENG_ID},		{"ISFT", ISFT_ID},		{"ICMT", ICMT_ID},	};	int i;	for (i = 0; i < sizeof(idlist)/sizeof(idlist[0]); i++) {		if (strncmp(id, idlist[i].str, 4) == 0)			return idlist[i].id;	}	return UNKN_ID;}/*================================================================ * process a list chunk *================================================================*/static int process_list(int size, SFInfo *sf, struct timidity_file *fd){	SFChunk chunk;	/* read the following id string */	READID(chunk.id, fd); size -= 4;	ctl->cmsg(CMSG_INFO, VERB_DEBUG, "%c%c%c%c:",		  chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]);	switch (chunkid(chunk.id)) {	case INFO_ID:		return process_info(size, sf, fd);	case SDTA_ID:		return process_sdta(size, sf, fd);	case PDTA_ID:		return process_pdta(size, sf, fd);	default:		ctl->cmsg(CMSG_WARNING, VERB_NORMAL,			  "%s: *** illegal id in level 1: %4.4s",			  current_filename, chunk.id);		FSKIP(size, fd); /* skip it */		return 0;	}}			/*================================================================ * process info list *================================================================*/		static int process_info(int size, SFInfo *sf, struct timidity_file *fd){	sf->infopos = tf_tell(fd);	sf->infosize = size;		/* parse the buffer */	while (size > 0) {		SFChunk chunk;		/* read a sub chunk */		if(READCHUNK(&chunk, fd) <= 0)		    return -1;		size -= 8;		ctl->cmsg(CMSG_INFO, VERB_DEBUG, " %c%c%c%c:",			  chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]);		switch (chunkid(chunk.id)) {		case IFIL_ID:			/* soundfont file version */			READW(&sf->version, fd);			READW(&sf->minorversion, fd);			ctl->cmsg(CMSG_INFO, VERB_DEBUG,				  "  version %d, minor %d",				  sf->version, sf->minorversion);			break;		case INAM_ID:			/* name of the font */			sf->sf_name = (char*)safe_malloc(chunk.size + 1);			tf_read(sf->sf_name, 1, chunk.size, fd);			sf->sf_name[chunk.size] = 0;			ctl->cmsg(CMSG_INFO, VERB_DEBUG,				  "  name %s", sf->sf_name);			break;					default:			if(ctl->verbosity >= VERB_DEBUG)			{			    char buff[100];			    if(chunk.size < sizeof(buff) - 1)			    {				tf_read(buff, chunk.size, 1, fd);				buff[chunk.size] = '\0';			    }			    else			    {				int i = sizeof(buff) - 4;				tf_read(buff, i, 1, fd);				FSKIP(chunk.size - i, fd);				buff[i++] = '.';				buff[i++] = '.';				buff[i++] = '.';				buff[i] = '\0';			    }			    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "  %s", buff);			}			else			    FSKIP(chunk.size, fd);			break;		}		size -= chunk.size;	}	return 0;}

⌨️ 快捷键说明

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