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

📄 smplfile.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 3 页
字号:
		else			modes = 0;		for(i = 0; i < samples; i++)		{			sample = &inst->sample[i];			sample->sample_rate = sample_rate;			sample->root_freq = root_freq;			if (modes != 0)			{				sample->loop_start = loopStart;				sample->loop_end = loopEnd;			}			sample->modes |= modes;		}	}	if (chunk_flags & WAVE_CHUNKFLAG_INSTRUMENT)		apply_GeneralInstrumentInfo(samples, inst->sample, &instc);	return (state != 2);}static int read_WAVFormatChunk(struct timidity_file *tf, WAVFormatChunk *fmt, int csize){	int32		tmplong;	int16		tmpshort;		READ_SHORT_LE(fmt->wFormatTag);	READ_SHORT_LE(fmt->wChannels);	READ_LONG_LE(fmt->dwSamplesPerSec);	READ_LONG_LE(fmt->dwAvgBytesPerSec);	READ_SHORT_LE(fmt->wBlockAlign);	READ_SHORT_LE(fmt->wBitsPerSample);	if (tf_seek(tf, csize - 0x10, SEEK_CUR) == -1)		goto fail;	return 1;	fail:		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Unable to read format chunk");		return 0;}static int read_WAVSamplerChunk(struct timidity_file *tf, WAVSamplerChunk *smpl, int psize){	int32		tmplong;	int			i, loopCount, cbSamplerData, dwPlayCount;	unsigned int	loopType;		smpl->hasLoop = 0;	/* skip dwManufacturer, dwProduct */	if (tf_seek(tf, 4 + 4, SEEK_CUR) == -1)		goto fail;	READ_LONG_LE(smpl->dwSamplePeriod);	READ_LONG_LE(smpl->dwMIDIUnityNote);	READ_LONG_LE(smpl->dwMIDIPitchFraction);	/* skip dwSMPTEFormat, dwSMPTEOffset */	if (tf_seek(tf, 4 + 4, SEEK_CUR) == -1)		goto fail;	READ_LONG_LE(loopCount);	READ_LONG_LE(cbSamplerData);	psize -= 4 * 9 + loopCount * 4 * 6;	for(i = 0; i < loopCount; i++)	{		/* skip dwIdentifier */		if (tf_seek(tf, 4, SEEK_CUR) == -1)			goto fail;		READ_LONG_LE(loopType);	/* dwType */		if (!smpl->hasLoop && loopType <= 2)		{			smpl->loopType = loopType;			READ_LONG_LE(smpl->loop_dwStart);			READ_LONG_LE(smpl->loop_dwEnd);			READ_LONG_LE(smpl->loop_dwFraction);			READ_LONG_LE(dwPlayCount);			if (dwPlayCount == 0)	/* infinite loop */				smpl->hasLoop = 1;		}		else		{			if (tf_seek(tf, 4 * 4, SEEK_CUR) == -1)				goto fail;		}	}	if (psize != cbSamplerData)		ctl->cmsg(CMSG_WARNING, VERB_NOISY, "Bad sampler chunk length");	if (tf_seek(tf, psize, SEEK_CUR) == -1)		goto fail;	ctl->cmsg(CMSG_INFO, VERB_NOISY, "Sampler: %dns/frame, note=%d, loops=%d",				smpl->dwSamplePeriod, smpl->dwMIDIUnityNote, loopCount);	return 1;	fail:		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Unable to read sampler chunk");		return 0;}static int read_WAVInstrumentChunk(struct timidity_file *tf, GeneralInstrumentInfo *inst, int psize){	int8		tmpchar;		if (psize != 7)		goto fail;	READ_CHAR(inst->baseNote);	READ_CHAR(inst->detune);	READ_CHAR(inst->gain);	READ_CHAR(inst->lowNote);	READ_CHAR(inst->highNote);	READ_CHAR(inst->lowVelocity);	READ_CHAR(inst->highVelocity);	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;}/*************** AIFF importer ***************/typedef struct {	uint16			numChannels;	uint32			numSampleFrames;	uint16			sampleSize;	double			sampleRate;} AIFFCommonChunk;typedef struct {	uint32			position;	Instrument		*inst;	AIFFCommonChunk	*common;} AIFFSoundDataChunk;typedef struct {	uint16			mode;	int16			beginID, endID;} AIFFLoopInfo;typedef struct {	int16			id;	uint32			position;} AIFFMarkerData;static int read_AIFFCommonChunk(struct timidity_file *tf, AIFFCommonChunk *comm, int csize, int compressed);static int read_AIFFSoundDataChunk(struct timidity_file *tf, AIFFSoundDataChunk *sound, int csize, int mode);static int read_AIFFSoundData(struct timidity_file *tf, Instrument *inst, AIFFCommonChunk *common);static int read_AIFFInstumentChunk(struct timidity_file *tf, GeneralInstrumentInfo *inst, AIFFLoopInfo *loop, int csize);static int read_AIFFMarkerChunk(struct timidity_file *tf, AIFFMarkerData **markers, int csize);static int AIFFGetMarkerPosition(int16 id, const AIFFMarkerData *markers, uint32 *position);static int import_aiff_discriminant(char *sample_file){	struct timidity_file	*tf;	char				buf[12];		if ((tf = open_file(sample_file, 1, OF_NORMAL)) == NULL)		return 1;	if (tf_read(buf, 12, 1, tf) != 1			|| memcmp(&buf[0], "FORM", 4) != 0 || memcmp(&buf[8], "AIF", 3) != 0			|| (buf[8 + 3] != 'F' && buf[8 + 3] != 'C'))	{		close_file(tf);		return 1;	}	close_file(tf);	return 0;}#define AIFF_CHUNKFLAG_COMMON		(1 << 0)#define AIFF_CHUNKFLAG_SOUND		(1 << 1)#define AIFF_CHUNKFLAG_INSTRUMENT	(1 << 2)#define AIFF_CHUNKFLAG_MARKER		(1 << 3)#define AIFF_CHUNKFLAG_SOUNDREAD	(1 << 29)#define AIFF_CHUNKFLAG_READERR		(1 << 30)#define AIFF_CHUNKFLAG_DUPCHUNK		(1 << 31)#define AIFF_CHUNKFLAG_REQUIRED		(AIFF_CHUNKFLAG_COMMON | AIFF_CHUNKFLAG_SOUND)#define AIFF_CHUNKFLAG_FAILED		(AIFF_CHUNKFLAG_READERR | AIFF_CHUNKFLAG_DUPCHUNK)static int import_aiff_load(char *sample_file, Instrument *inst){	struct timidity_file	*tf;	char			buf[12];	int				chunk_size, type_index, type_size;	int				compressed;	int32			chunk_flags;	AIFFCommonChunk	common;	AIFFSoundDataChunk	sound;	GeneralInstrumentInfo	inst_info;	AIFFLoopInfo	loop_info;	AIFFMarkerData	*marker_data;		if ((tf = open_file(sample_file, 1, OF_NORMAL)) == NULL)		return 1;	if (tf_read(buf, 12, 1, tf) != 1			|| memcmp(&buf[0], "FORM", 4) != 0 || memcmp(&buf[8], "AIF", 3) != 0			|| (buf[8 + 3] != 'F' && buf[8 + 3] != 'C'))	{		close_file(tf);		return 1;	}	compressed = buf[8 + 3] == 'C';	ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading AIFF: %s", sample_file);	type_index = 4, type_size = 8;	chunk_flags = 0;	sound.inst = inst;	sound.common = &common;	marker_data = NULL;	for(;;) {		if (tf_read(&buf[type_index], type_size, 1, tf) != 1)			break;		chunk_size = BE_LONG(*(int32 *)&buf[4 + 4]);		if (memcmp(&buf[4 + 0], "COMM", 4) == 0)		{			if (chunk_flags & AIFF_CHUNKFLAG_COMMON)			{				chunk_flags |= AIFF_CHUNKFLAG_DUPCHUNK;				break;			}			if (chunk_size < 18)	/* too small */				break;			if (!read_AIFFCommonChunk(tf, &common, chunk_size, compressed))				break;			chunk_flags |= AIFF_CHUNKFLAG_COMMON;		}		else if (memcmp(&buf[4 + 0], "SSND", 4) == 0)		{			if (chunk_flags & AIFF_CHUNKFLAG_SOUND)			{				chunk_flags |= AIFF_CHUNKFLAG_DUPCHUNK;				break;			}			if (chunk_flags & AIFF_CHUNKFLAG_COMMON)			{				if (!read_AIFFSoundDataChunk(tf, &sound, chunk_size, 0))					break;				chunk_flags |= AIFF_CHUNKFLAG_SOUNDREAD;			}			else if (!read_AIFFSoundDataChunk(tf, &sound, chunk_size, 1))				break;			chunk_flags |= AIFF_CHUNKFLAG_SOUND;		}		else if (memcmp(&buf[4 + 0], "INST", 4) == 0)		{			if (chunk_flags & AIFF_CHUNKFLAG_INSTRUMENT)			{				chunk_flags |= AIFF_CHUNKFLAG_DUPCHUNK;				break;			}			else if (!read_AIFFInstumentChunk(tf, &inst_info, &loop_info, chunk_size))				break;			chunk_flags |= AIFF_CHUNKFLAG_INSTRUMENT;		}		else if (memcmp(&buf[4 + 0], "MARK", 4) == 0)		{			if (chunk_flags & AIFF_CHUNKFLAG_MARKER)			{				chunk_flags |= AIFF_CHUNKFLAG_DUPCHUNK;				break;			}			else if (chunk_size < 2 || !read_AIFFMarkerChunk(tf, &marker_data, chunk_size))				break;			chunk_flags |= AIFF_CHUNKFLAG_MARKER;		}		else if (inst->instname == NULL && memcmp(&buf[4 + 0], "NAME", 4) == 0)		{			inst->instname = malloc(chunk_size + 1);			if (tf_read(inst->instname, chunk_size, 1, tf) != 1)			{				chunk_flags |= AIFF_CHUNKFLAG_READERR;				break;			}			inst->instname[chunk_size] = '\0';		}		else if (tf_seek(tf, chunk_size, SEEK_CUR) == -1)			break;		/* no need to check format version chunk */		type_index = 4 - (chunk_size & 1);		type_size = 8 + (chunk_size & 1);	}	if (chunk_flags & AIFF_CHUNKFLAG_FAILED			|| (chunk_flags & AIFF_CHUNKFLAG_REQUIRED) != AIFF_CHUNKFLAG_REQUIRED)	{		if (marker_data != NULL)			free(marker_data);		close_file(tf);		return -1;	}	if (!(chunk_flags & AIFF_CHUNKFLAG_SOUNDREAD))	{		if (!read_AIFFSoundDataChunk(tf, &sound, 0, 2))		{			if (marker_data != NULL)				free(marker_data);			close_file(tf);			return 1;		}	}	if (chunk_flags & AIFF_CHUNKFLAG_INSTRUMENT)	{		apply_GeneralInstrumentInfo(inst->samples, inst->sample, &inst_info);		if ((loop_info.mode == 1 || loop_info.mode == 2)				&& chunk_flags & AIFF_CHUNKFLAG_MARKER && marker_data != NULL)		{			Sample			*sample;			int				i;			uint32			loopStart, loopEnd;			uint8			loopMode;						if (AIFFGetMarkerPosition(loop_info.beginID, marker_data, &loopStart)					&& AIFFGetMarkerPosition(loop_info.endID, marker_data, &loopEnd))			{				loopMode = (loop_info.mode == 1) ? MODES_LOOPING : (MODES_LOOPING | MODES_PINGPONG);				loopStart <<= FRACTION_BITS;				loopEnd <<= FRACTION_BITS;				if (loopStart <= loopEnd)				{					for(i = 0; i < inst->samples; i++)					{						sample = &inst->sample[i];						sample->loop_start = loopStart;						sample->loop_end = loopEnd;						sample->modes |= loopMode;					}				}			}		}	}	if (marker_data != NULL)		free(marker_data);	close_file(tf);	return 0;}static int read_AIFFCommonChunk(struct timidity_file *tf, AIFFCommonChunk *comm, int csize, int compressed){	int32		tmplong;	int16		tmpshort;	int8		tmpchar;	char		sampleRate[10];	uint32		compressionType;		READ_SHORT_BE(comm->numChannels);	READ_LONG_BE(comm->numSampleFrames);	READ_SHORT_BE(comm->sampleSize);	if (tf_read(sampleRate, 10, 1, tf) != 1)		goto fail;	comm->sampleRate = ConvertFromIeeeExtended(sampleRate);	csize -= 8 + 10;	ctl->cmsg(CMSG_INFO, VERB_NOISY, "Format: %d-bits %dHz %dch, %d frames",			comm->sampleSize, (int)comm->sampleRate, comm->numChannels, comm->numSampleFrames);	if (compressed)	{		READ_LONG_BE(compressionType);		if (compressionType != BE_LONG(0x4E4F4E45) /* NONE */)		{			char		compressionName[256];			uint8		compressionNameLength;						READ_CHAR(compressionNameLength);			if (tf_read(compressionName, compressionNameLength, 1, tf) != 1)				goto fail;			compressionName[compressionNameLength] = '\0';			ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "AIFF-C unknown compression type: %s", compressionName);			goto fail;		}		csize -= 4;		/* ignore compressionName and its padding */	}	if (tf_seek(tf, csize, SEEK_CUR) == -1)		goto fail;	return 1;	fail:		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Unable to read common chunk");		return 0;}static int read_AIFFSoundDataChunk(struct timidity_file *tf, AIFFSoundDataChunk *sound, int csize, int mode){	int32		tmplong;	uint32		offset, blockSize;		if (mode == 0 || mode == 1)	{		READ_LONG_BE(offset);		READ_LONG_BE(blockSize);		if (blockSize != 0)		/* not implemented */			goto fail;		if (mode == 0)		/* read both information and data */			return read_AIFFSoundData(tf, sound->inst, sound->common);		/* read information only */		if ((sound->position = tf_tell(tf)) == -1)			goto fail;		sound->position += offset;		csize -= 8;		if (tf_seek(tf, csize, SEEK_CUR) == -1)			goto fail;		return 1;	}	else if (mode == 2)		/* read data using information previously read */	{		if (tf_seek(tf, sound->position, SEEK_SET) == -1)			goto fail;		return read_AIFFSoundData(tf, sound->inst, sound->common);	}	fail:		ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Unable to read sound data chunk");		return 0;}static int read_AIFFSoundData(struct timidity_file *tf, Instrument *inst, AIFFCommonChunk *common){	int				i, samples;	Sample			*sample;	sample_t		*sdata[MAX_SAMPLE_CHANNELS];		if ((samples = common->numChannels) > MAX_SAMPLE_CHANNELS)		goto fail;	inst->samples = samples;	inst->sample = sample = (Sample *)safe_malloc(sizeof(Sample) * samples);	initialize_sample(inst, common->numSampleFrames, common->sampleSize, (int)common->sampleRate);	/* load samples */	for(i = 0; i < samples; i++)	{		sample[i].data = sdata[i] = (sample_t *)safe_malloc(sizeof(sample_t) * common->numSampleFrames);		sample[i].data_alloced = 1;	}

⌨️ 快捷键说明

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