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

📄 sffile.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*================================================================ * process sample data list *================================================================*/static int process_sdta(int size, SFInfo *sf, struct timidity_file *fd){	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 SNAM_ID:			/* sample name list */			load_sample_names(chunk.size, sf, fd);			break;		case SMPL_ID:			/* sample data starts from here */			sf->samplepos = tf_tell(fd);			sf->samplesize = chunk.size;			FSKIP(chunk.size, fd);			break;		default:			FSKIP(chunk.size, fd);			break;		}		size -= chunk.size;	}	return 0;}/*================================================================ * process preset data list *================================================================*/static int process_pdta(int size, SFInfo *sf, struct timidity_file *fd){	while (size > 0) {		SFChunk chunk;		/* read a subchunk */		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 PHDR_ID:			load_preset_header(chunk.size, sf, fd);			break;		case PBAG_ID:			load_bag(chunk.size, &prbags, fd);			break;		case PGEN_ID:			load_gen(chunk.size, &prbags, fd);			break;		case INST_ID:			load_inst_header(chunk.size, sf, fd);			break;		case IBAG_ID:			load_bag(chunk.size, &inbags, fd);			break;		case IGEN_ID:			load_gen(chunk.size, &inbags, fd);			break;		case SHDR_ID:			load_sample_info(chunk.size, sf, fd);			break;		case PMOD_ID: /* ignored */		case IMOD_ID: /* ingored */		default:			FSKIP(chunk.size, fd);			break;		}		size -= chunk.size;	}	return 0;}/*---------------------------------------------------------------- * store sample name list; sf1 only *----------------------------------------------------------------*/static void load_sample_names(int size, SFInfo *sf, struct timidity_file *fd){	int i, nsamples;	if (sf->version > 1) {		ctl->cmsg(CMSG_WARNING, VERB_NORMAL,			  "%s: *** version 2 has obsolete format??",			  current_filename);		FSKIP(size, fd);		return;	}	/* each sample name has a fixed lentgh (20 bytes) */	nsamples = size / 20;	if (sf->sample == NULL) {		sf->nsamples = nsamples;		sf->sample = NEW(SFSampleInfo, sf->nsamples);	} else if (sf->nsamples != nsamples) {		ctl->cmsg(CMSG_WARNING, VERB_NORMAL,			  "%s: *** different # of samples ?? (%d : %d)\n",			  current_filename, sf->nsamples, nsamples);		FSKIP(size, fd);		return;	}			/* read each name from file */	for (i = 0; i < sf->nsamples; i++) {		READSTR(sf->sample[i].name, fd);	}}/*---------------------------------------------------------------- * preset header list *----------------------------------------------------------------*/static void load_preset_header(int size, SFInfo *sf, struct timidity_file *fd){	int i;	sf->npresets = size / 38;	sf->preset = NEW(SFPresetHdr, sf->npresets);	for (i = 0; i < sf->npresets; i++) {		READSTR(sf->preset[i].hdr.name, fd);		READW(&sf->preset[i].preset, fd);		READW(&sf->preset[i].bank, fd);		READW(&sf->preset[i].hdr.bagNdx, fd);		SKIPDW(fd); /* lib; ignored*/		SKIPDW(fd); /* genre; ignored */		SKIPDW(fd); /* morph; ignored */		/* initialize layer table; it'll be parsed later */		sf->preset[i].hdr.nlayers = 0;		sf->preset[i].hdr.layer = NULL;		ctl->cmsg(CMSG_INFO, VERB_DEBUG,			  "  Preset %d (%s) index=%d bank=%d preset=%d",			  i, sf->preset[i].hdr.name,			  sf->preset[i].hdr.bagNdx,			  sf->preset[i].bank,			  sf->preset[i].preset + progbase);	}}/*---------------------------------------------------------------- * instrument header list *----------------------------------------------------------------*/static void load_inst_header(int size, SFInfo *sf, struct timidity_file *fd){	int i;	sf->ninsts = size / 22;	sf->inst = NEW(SFInstHdr, sf->ninsts);	for (i = 0; i < sf->ninsts; i++) {		READSTR(sf->inst[i].hdr.name, fd);		READW(&sf->inst[i].hdr.bagNdx, fd);		/* iniitialize layer table; it'll be parsed later */		sf->inst[i].hdr.nlayers = 0;		sf->inst[i].hdr.layer = NULL;		ctl->cmsg(CMSG_INFO, VERB_DEBUG,			  "  InstHdr %d (%s) bagNdx=%d",			  i, sf->inst[i].hdr.name, sf->inst[i].hdr.bagNdx);	}}/*---------------------------------------------------------------- * load preset/instrument bag list on the private table *----------------------------------------------------------------*/static void load_bag(int size, SFBags *bagp, struct timidity_file *fd){	int i;	size /= 4;	bagp->bag = NEW(uint16, size);	for (i = 0; i < size; i++) {		READW(&bagp->bag[i], fd);		SKIPW(fd); /* mod; ignored */	}	bagp->nbags = size;}/*---------------------------------------------------------------- * load preset/instrument generator list on the private table *----------------------------------------------------------------*/static void load_gen(int size, SFBags *bagp, struct timidity_file *fd){	int i;	size /= 4;	bagp->gen = NEW(SFGenRec, size);	for (i = 0; i < size; i++) {		READW((uint16 *)&bagp->gen[i].oper, fd);		READW((uint16 *)&bagp->gen[i].amount, fd);	}	bagp->ngens = size;}/*---------------------------------------------------------------- * load sample info list *----------------------------------------------------------------*/static void load_sample_info(int size, SFInfo *sf, struct timidity_file *fd){	int i;	int in_rom;	/* the record size depends on the soundfont version */	if (sf->version > 1) {		/* SF2 includes sample name and other infos */		sf->nsamples = size / 46;		sf->sample = NEW(SFSampleInfo, sf->nsamples);	} else  {		/* SBK; sample name may be read already */		int nsamples = size / 16;		if (sf->sample == NULL) {			sf->nsamples = nsamples;			sf->sample = NEW(SFSampleInfo, sf->nsamples);		} else if (sf->nsamples != nsamples) {#if 0			fprintf(stderr, "*** different # of infos ?? (%d : %d)\n",			       sf->nsamples, nsamples);			FSKIP(size, fd);			return;#endif			/* overwrite it */			sf->nsamples = nsamples;		}	}	in_rom = 1;  /* data may start from ROM samples */	for (i = 0; i < sf->nsamples; i++) {		if (sf->version > 1) /* SF2 only */			READSTR(sf->sample[i].name, fd);		READDW((uint32 *)&sf->sample[i].startsample, fd);		READDW((uint32 *)&sf->sample[i].endsample, fd);		READDW((uint32 *)&sf->sample[i].startloop, fd);		READDW((uint32 *)&sf->sample[i].endloop, fd);		if (sf->version > 1) { /* SF2 only */			READDW((uint32 *)&sf->sample[i].samplerate, fd);			READB(sf->sample[i].originalPitch, fd);			READB(sf->sample[i].pitchCorrection, fd);			READW(&sf->sample[i].samplelink, fd);			READW(&sf->sample[i].sampletype, fd);		} else { /* for SBK; set missing infos */			sf->sample[i].samplerate = 44100;			sf->sample[i].originalPitch = 60;			sf->sample[i].pitchCorrection = 0;			sf->sample[i].samplelink = 0;			/* the first RAM data starts from address 0 */			if (sf->sample[i].startsample == 0)				in_rom = 0;			if (in_rom)				sf->sample[i].sampletype = 0x8001;			else				sf->sample[i].sampletype = 1;		}	}}/*================================================================ * convert from bags to layers *================================================================*/static void convert_layers(SFInfo *sf){	int i;	if (prbags.bag == NULL || prbags.gen == NULL ||	    inbags.bag == NULL || inbags.gen == NULL) {		ctl->cmsg(CMSG_WARNING, VERB_NORMAL,			  "%s: *** illegal bags / gens", current_filename);		return;	}	for (i = 0; i < sf->npresets - 1; i++) {		generate_layers(&sf->preset[i].hdr,				&sf->preset[i+1].hdr,				&prbags);	}	for (i = 0; i < sf->ninsts - 1; i++) {		generate_layers(&sf->inst[i].hdr,				&sf->inst[i+1].hdr,				&inbags);	}}/*---------------------------------------------------------------- * generate layer lists from stored bags *----------------------------------------------------------------*/static void generate_layers(SFHeader *hdr, SFHeader *next, SFBags *bags){	int i;	SFGenLayer *layp;		hdr->nlayers = next->bagNdx - hdr->bagNdx;	if (hdr->nlayers < 0) {		ctl->cmsg(CMSG_WARNING, VERB_NORMAL,			  "%s: illegal layer numbers %d",			  current_filename, hdr->nlayers);		return;	}	if (hdr->nlayers == 0)		return;	hdr->layer = (SFGenLayer*)safe_malloc(sizeof(SFGenLayer) * hdr->nlayers);	layp = hdr->layer;	for (layp = hdr->layer, i = hdr->bagNdx; i < next->bagNdx; layp++, i++) {		int genNdx = bags->bag[i];		layp->nlists = bags->bag[i+1] - genNdx;		if (layp->nlists < 0) {			ctl->cmsg(CMSG_WARNING, VERB_NORMAL,				  "%s: illegal list numbers %d",				  current_filename, layp->nlists);			return;		}		layp->list = (SFGenRec*)safe_malloc(sizeof(SFGenRec) * layp->nlists);		memcpy(layp->list, &bags->gen[genNdx],		       sizeof(SFGenRec) * layp->nlists);	}}/*---------------------------------------------------------------- * free a layer *----------------------------------------------------------------*/static void free_layer(SFHeader *hdr){	int i;	for (i = 0; i < hdr->nlayers; i++) {		SFGenLayer *layp = &hdr->layer[i];		if (layp->nlists > 0)			free(layp->list);	}	if (hdr->nlayers > 0)		free(hdr->layer);}/* add blank loop for each data */int auto_add_blank = 0;void correct_samples(SFInfo *sf){	int i;	SFSampleInfo *sp;	int prev_end;	prev_end = 0;	for (sp = sf->sample, i = 0; i < sf->nsamples; i++, sp++) {		/* correct sample positions for SBK file */		if (sf->version == 1) {			sp->startloop++;			sp->endloop += 2;		}		/* calculate sample data size */		if (sp->sampletype & 0x8000)			sp->size = 0;		else if (sp->startsample < prev_end && sp->startsample != 0)			sp->size = 0;		else {			sp->size = -1;			if (!auto_add_blank && i != sf->nsamples-1)				sp->size = sp[1].startsample - sp->startsample;			if (sp->size < 0)				sp->size = sp->endsample - sp->startsample + 48;		}		prev_end = sp->endsample;		/* calculate short-shot loop size */		if (auto_add_blank || i == sf->nsamples-1)			sp->loopshot = 48;		else {			sp->loopshot = sp[1].startsample - sp->endsample;			if (sp->loopshot < 0 || sp->loopshot > 48)				sp->loopshot = 48;		}	}}

⌨️ 快捷键说明

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