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

📄 smplfile.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (!read_sample_data(SAMPLE_BIG_ENDIAN, tf, common->sampleSize, samples, common->numSampleFrames, sdata))		goto fail;	return 1;	fail:		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Unable to read sound data");		return 0;}static int read_AIFFInstumentChunk(struct timidity_file *tf, GeneralInstrumentInfo *inst, AIFFLoopInfo *loop, int csize){	int8		tmpchar;	int16		tmpshort;		if (csize != 20)	{		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Bad instrument chunk length");		if (tf_seek(tf, csize, SEEK_CUR) == -1)			goto fail;		return 1;	}	READ_CHAR(inst->baseNote);	READ_CHAR(inst->detune);	READ_CHAR(inst->lowNote);	READ_CHAR(inst->highNote);	READ_CHAR(inst->lowVelocity);	READ_CHAR(inst->highVelocity);	READ_SHORT_BE(inst->gain);	READ_SHORT_BE(loop->mode);	/* sustain loop */	READ_SHORT_BE(loop->beginID);	READ_SHORT_BE(loop->endID);	if (tf_seek(tf, 2 + 2 + 2, SEEK_CUR) == -1)	/* release loop */		goto fail;	ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "Instrument: note=%d (%d-%d), gain=%ddb, velocity=%d-%d",				inst->baseNote, inst->lowNote, inst->highNote, inst->gain,				inst->lowVelocity, inst->highVelocity);	return 1;	fail:		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Unable to read instrument chunk");		return 0;}static int read_AIFFMarkerChunk(struct timidity_file *tf, AIFFMarkerData **markers, int csize){	int32		tmplong;	int16		tmpshort;	int16			markerCount;	int				i, dest;	AIFFMarkerData	*m;		m = NULL;	READ_SHORT_BE(markerCount)	if (csize != 2 + markerCount * (2 + 4))	{		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Bad marker chunk length");		if (tf_seek(tf, csize, SEEK_CUR) == -1)			goto fail;		return 1;	}	if ((m = malloc(sizeof(AIFFMarkerData) * (markerCount + 1))) == NULL)		goto fail;	for(i = dest = 0; i < markerCount; i++)	{		READ_SHORT_BE(m[dest].id);		READ_LONG_BE(m[dest].position);		if (m[dest].id > 0)			dest++; 	}	m[dest].id = 0;	*markers = m;	return 1;	fail:		if (m != NULL)			free(m);		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Unable to read marker chunk");		return 0;}static int AIFFGetMarkerPosition(int16 id, const AIFFMarkerData *markers, uint32 *position){	const AIFFMarkerData	*marker;		marker = markers;	while(marker->id != 0)	{		if (marker->id == id)		{			*position = marker->position;			return 1;		}		marker++;	}	return 0;}/******************************/#define WAVE_BUF_SIZE		(1 << 11)	/* should be power of 2 */#define READ_WAVE_SAMPLE(dest, b, s)	\				if (tf_read(dest, (b) * (s), 1, tf) != 1)	\					goto fail#define READ_WAVE_FRAME(dest, b, f)	\				READ_WAVE_SAMPLE(dest, b, (f) * channels)#define BITS_S8_TO_16(n)	((uint16)((n) << 8) | ((n) ^ 0x80))#define BITS_U8_TO_16(n)	((uint16)(((n) ^ 0x80) << 8) | (n))#define BLOCK_READ_BEGIN(stype, sbyte, fch)	{ /* sbyte may be sizeof(stype) */	\			stype				data[WAVE_BUF_SIZE / sizeof(stype)];	\			int					j;	\			for(block_frame_count = (sizeof data / sbyte / fch); block_frame_count != 0; block_frame_count >>= 1) {	\				while(i <= frames - block_frame_count) {	\					READ_WAVE_FRAME(data, sbyte, block_frame_count);	\					for(j = 0; j < (block_frame_count * (fch)); i++)#define BLOCK_READ_END		} } }static int read_sample_data(int32 flags, struct timidity_file *tf, int bits, int channels, int frames, sample_t **sdata){	int				i, block_frame_count;		i = 0;	if (bits == 16)	{		if (channels == 1)		{			READ_WAVE_SAMPLE(sdata[0], 2, frames);			if (flags & SAMPLE_BIG_ENDIAN) {				#ifdef LITTLE_ENDIAN				for(i = 0; i < frames; i++)					sdata[0][i] = BE_SHORT(sdata[0][i]);				#endif			} else {				#ifdef BIG_ENDIAN				for(i = 0; i < frames; i++)					sdata[0][i] = LE_SHORT(sdata[0][i]);				#endif			}		} else {			if (flags & SAMPLE_BIG_ENDIAN) {				BLOCK_READ_BEGIN(uint16, 2, channels)				{					int c;					for(c = 0; c < channels; c++, j++)						sdata[c][i] = BE_SHORT(data[j]);				}				BLOCK_READ_END			} else {				BLOCK_READ_BEGIN(uint16, 2, channels)				{					int c;					for(c = 0; c < channels; c++, j++)						sdata[c][i] = LE_SHORT(data[j]);				}				BLOCK_READ_END			}		}	}	else	{		if (channels == 1)		{			if (flags & SAMPLE_8BIT_UNSIGNED) {				BLOCK_READ_BEGIN(uint8, 1, 1)				{					sdata[0][i] = BITS_U8_TO_16(data[j]); j++;				}				BLOCK_READ_END			} else {				BLOCK_READ_BEGIN(uint8, 1, 1)				{					sdata[0][i] = BITS_S8_TO_16(data[j]); j++;				}				BLOCK_READ_END			}		} else {			if (flags & SAMPLE_8BIT_UNSIGNED) {				BLOCK_READ_BEGIN(uint8, 1, channels)				{					int c;					for(c = 0; c < channels; c++, j++)						sdata[c][i] = BITS_U8_TO_16(data[j]);				}				BLOCK_READ_END			} else {				BLOCK_READ_BEGIN(uint8, 1, channels)				{					int c;					for(c = 0; c < channels; c++, j++)						sdata[c][i] = BITS_S8_TO_16(data[j]);				}				BLOCK_READ_END			}		}	}	return 1;	fail:		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Unable to read sample data");		return 0;}/* from instrum.c */static int32 convert_envelope_rate(uint8 rate){  int32 r;  r=3-((rate>>6) & 0x3);  r*=3;  r = (int32)(rate & 0x3f) << r; /* 6.9 fixed point */  /* 15.15 fixed point. */  return (((r * 44100) / play_mode->rate) * control_ratio)    << ((fast_decay) ? 10 : 9);}/* from instrum.c */static int32 convert_envelope_offset(uint8 offset){  /* This is not too good... Can anyone tell me what these values mean?     Are they GUS-style "exponential" volumes? And what does that mean? */  /* 15.15 fixed point */  return offset << (7+15);}static void initialize_sample(Instrument *inst, int frames, int sample_bits, int sample_rate){	int				i, j, samples;	Sample			*sample;	const uint8		*panning;		samples = inst->samples;	for(i = 0; i < samples; i++)	{		sample = &inst->sample[i];		sample->data_alloced = 0;		sample->loop_start = 0;		sample->loop_end = sample->data_length = frames << FRACTION_BITS;		sample->sample_rate = sample_rate;		sample->low_freq = freq_table[0];		sample->high_freq = freq_table[127];		sample->root_freq = freq_table[60];		sample->panning = 64;		sample->note_to_use = 0;		sample->volume = 1.0;		sample->modes = MODES_16BIT;		sample->low_vel = 0;		sample->high_vel = 127;		sample->tremolo_sweep_increment =			sample->tremolo_phase_increment = sample->tremolo_depth =			sample->vibrato_sweep_increment = sample->vibrato_control_ratio = sample->vibrato_depth = 0;		sample->cutoff_freq = sample->resonance = sample->tremolo_to_pitch = 			sample->tremolo_to_fc = sample->modenv_to_pitch = sample->modenv_to_fc =			sample->vel_to_fc = sample->key_to_fc = sample->vel_to_resonance = 0;		sample->envelope_velf_bpo = sample->modenv_velf_bpo =			sample->vel_to_fc_threshold = 64;		sample->key_to_fc_bpo = 60;		sample->scale_freq = 60;		sample->scale_factor = 1024;		memset(sample->envelope_velf, 0, sizeof(sample->envelope_velf));		memset(sample->envelope_keyf, 0, sizeof(sample->envelope_keyf));		memset(sample->modenv_velf, 0, sizeof(sample->modenv_velf));		memset(sample->modenv_keyf, 0, sizeof(sample->modenv_keyf));		memset(sample->modenv_rate, 0, sizeof(sample->modenv_rate));		memset(sample->modenv_offset, 0, sizeof(sample->modenv_offset));		sample->envelope_delay = sample->modenv_delay =			sample->tremolo_delay = sample->vibrato_delay = 0;		sample->inst_type = INST_PCM;		sample->sample_type = SF_SAMPLETYPE_MONO;		sample->sf_sample_link = -1;		sample->sf_sample_index = 0;	}	if (samples <= 6 && (panning = gen_pan_list[samples - 1]) != NULL)	{		for(i = 0; i < samples; i++)			inst->sample[i].panning = panning[i];	}	for(i = 0; i < 6; i++)	{		int32			envelope_rate, envelope_offset;			envelope_rate = convert_envelope_rate(63);	/* wav2pat.c */		envelope_offset = convert_envelope_offset(240);	/* wav2pat.c */		for(j = 0; j < samples; j++)		{			sample = &inst->sample[j];			sample->envelope_rate[i] = envelope_rate;			sample->envelope_offset[i] = envelope_offset;		}	}}static void apply_GeneralInstrumentInfo(int samples, Sample *sample, const GeneralInstrumentInfo *info){	int32		root_freq;	FLOAT_T		gain;	int			i;		root_freq = freq_table[info->baseNote];	if (info->detune < 0)	{		if (info->baseNote != 0)	/* no table data */			root_freq += (root_freq - freq_table[info->baseNote - 1]) * 50 / info->detune;	}	else if (info->detune > 0)	{		if (info->baseNote != 127)	/* no table data */			root_freq += (freq_table[info->baseNote + 1] - root_freq) * 50 / info->detune;	}	gain = pow(10, info->gain / 20.0);	for(i = 0; i < samples; i++)	{		sample[i].low_freq = freq_table[info->lowNote];		sample[i].high_freq = freq_table[info->highNote];		sample[i].root_freq = root_freq;		sample[i].volume *= gain;		sample[i].low_vel = info->lowVelocity;		sample[i].high_vel = info->highVelocity;	}}/* Copyright (C) 1989-1991 Ken Turkowski. <turk@computer.org> * * All rights reserved. * * Warranty Information *  Even though I have reviewed this software, I make no warranty *  or representation, either express or implied, with respect to this *  software, its quality, accuracy, merchantability, or fitness for a *  particular purpose.  As a result, this software is provided "as is," *  and you, its user, are assuming the entire risk as to its quality *  and accuracy. * * This code may be used and freely distributed as long as it includes * this copyright notice and the above warranty information. * * Machine-independent I/O routines for IEEE floating-point numbers. * * NaN's and infinities are converted to HUGE_VAL or HUGE, which * happens to be infinity on IEEE machines.  Unfortunately, it is * impossible to preserve NaN's in a machine-independent way. * Infinities are, however, preserved on IEEE machines. * * These routines have been tested on the following machines: *	Apple Macintosh, MPW 3.1 C compiler *	Apple Macintosh, THINK C compiler *	Silicon Graphics IRIS, MIPS compiler *	Cray X/MP and Y/MP *	Digital Equipment VAX *	Sequent Balance (Multiprocesor 386) *	NeXT * * * Implemented by Malcolm Slaney and Ken Turkowski. * * Malcolm Slaney contributions during 1988-1990 include big- and little- * endian file I/O, conversion to and from Motorola's extended 80-bit * floating-point format, and conversions to and from IEEE single- * precision floating-point format. * * In 1991, Ken Turkowski implemented the conversions to and from * IEEE double-precision format, added more precision to the extended * conversions, and accommodated conversions involving +/- infinity, * NaN's, and denormalized numbers. */#ifndef HUGE_VAL# define HUGE_VAL HUGE#endif /* HUGE_VAL *//**************************************************************** * The following two routines make up for deficiencies in many * compilers to convert properly between unsigned integers and * floating-point.  Some compilers which have this bug are the * THINK_C compiler for the Macintosh and the C compiler for the * Silicon Graphics MIPS-based Iris. ****************************************************************/# define UnsignedToFloat(u)	(((double)((long)((u) - 2147483647L - 1))) + 2147483648.0)/**************************************************************** * Extended precision IEEE floating-point conversion routines. * Extended is an 80-bit number as defined by Motorola, * with a sign bit, 15 bits of exponent (offset 16383?), * and a 64-bit mantissa, with no hidden bit. ****************************************************************/static double ConvertFromIeeeExtended(const char *bytes){	double	f;	long	expon;	unsigned long hiMant, loMant;		expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);	hiMant	=	((unsigned long)(bytes[2] & 0xFF) << 24)			|	((unsigned long)(bytes[3] & 0xFF) << 16)			|	((unsigned long)(bytes[4] & 0xFF) << 8)			|	((unsigned long)(bytes[5] & 0xFF));	loMant	=	((unsigned long)(bytes[6] & 0xFF) << 24)			|	((unsigned long)(bytes[7] & 0xFF) << 16)			|	((unsigned long)(bytes[8] & 0xFF) << 8)			|	((unsigned long)(bytes[9] & 0xFF));	if (expon == 0 && hiMant == 0 && loMant == 0) {		f = 0;	}	else {		if (expon == 0x7FFF) {	/* Infinity or NaN */			f = HUGE_VAL;		}		else {			expon -= 16383;			f  = ldexp(UnsignedToFloat(hiMant), expon-=31);			f += ldexp(UnsignedToFloat(loMant), expon-=32);		}	}	if (bytes[0] & 0x80)		return -f;	else		return f;}

⌨️ 快捷键说明

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