📄 smplfile.c
字号:
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 + -