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