/* If panning or note_to_use != -1, it will be used for all samples, instead of the sample-specific values in the instrument file. For note_to_use, any value <0 or >127 will be forced to 0. For other parameters, 1 means yes, 0 means no, other values are undefined. TODO: do reverse loops right */ static InstrumentLayer *load_instrument(char *name, int font_type, int percussion, int panning, int amp, int cfg_tuning, int note_to_use, int strip_loop, int strip_envelope, int strip_tail, int bank, int gm_num, int sf_ix) { InstrumentLayer *lp, *lastlp, *headlp; Instrument *ip; FILE *fp; uint8 tmp[1024]; int i,j,noluck=0; #ifdef PATCH_EXT_LIST static char *patch_ext[] = PATCH_EXT_LIST; #endif int sf2flag = 0; int right_samples = 0; int stereo_channels = 1, stereo_layer; int vlayer_list[19][4], vlayer, vlayer_count; if (!name) return 0; /* Open patch file */ if ((fp=open_file(name, 1, OF_NORMAL)) == NULL) { noluck=1; #ifdef PATCH_EXT_LIST /* Try with various extensions */ for (i=0; patch_ext[i]; i++) { if (strlen(name)+strlen(patch_ext[i])<1024) { char path[1024]; strcpy(path, name); strcat(path, patch_ext[i]); if ((fp=open_file(path, 1, OF_NORMAL)) != NULL) { noluck=0; break; } } } #endif } if (noluck) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Instrument `%s' can't be found.", name); return 0; } /*ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename);*/ /* Read some headers and do cursory sanity checks. There are loads of magic offsets. This could be rewritten... */ if ((239 != fread(tmp, 1, 239, fp)) || (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) && memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the differences are */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name); return 0; } /* patch layout: * bytes: info: starts at offset: * 22 id (see above) 0 * 60 copyright 22 * 1 instruments 82 * 1 voices 83 * 1 channels 84 * 2 number of waveforms 85 * 2 master volume 87 * 4 datasize 89 * 36 reserved, but now: 93 * 7 "SF2EXT\0" id 93 * 1 right samples 100 * 28 reserved 101 * 2 instrument number 129 * 16 instrument name 131 * 4 instrument size 147 * 1 number of layers 151 * 40 reserved 152 * 1 layer duplicate 192 * 1 layer number 193 * 4 layer size 194 * 1 number of samples 198 * 40 reserved 199 * 239 * THEN, for each sample, see below */ if (!memcmp(tmp + 93, "SF2EXT", 6)) { sf2flag = 1; vlayer_count = tmp[152]; } if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers, 0 means 1 */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle patches with %d instruments", tmp[82]); return 0; } if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle instruments with %d layers", tmp[151]); return 0; } if (sf2flag && vlayer_count > 0) { for (i = 0; i < 9; i++) for (j = 0; j < 4; j++) vlayer_list[i][j] = tmp[153+i*4+j]; for (i = 9; i < 19; i++) for (j = 0; j < 4; j++) vlayer_list[i][j] = tmp[199+(i-9)*4+j]; } else { for (i = 0; i < 19; i++) for (j = 0; j < 4; j++) vlayer_list[i][j] = 0; vlayer_list[0][0] = 0; vlayer_list[0][1] = 127; vlayer_list[0][2] = tmp[198]; vlayer_list[0][3] = 0; vlayer_count = 1; } lastlp = 0; for (vlayer = 0; vlayer < vlayer_count; vlayer++) { lp=(InstrumentLayer *)safe_malloc(sizeof(InstrumentLayer)); lp->size = sizeof(InstrumentLayer); lp->lo = vlayer_list[vlayer][0]; lp->hi = vlayer_list[vlayer][1]; ip=(Instrument *)safe_malloc(sizeof(Instrument)); lp->size += sizeof(Instrument); lp->instrument = ip; lp->next = 0; if (lastlp) lastlp->next = lp; else headlp = lp; lastlp = lp; if (sf2flag) ip->type = INST_SF2; else ip->type = INST_GUS; ip->samples = vlayer_list[vlayer][2]; ip->sample = (Sample *)safe_malloc(sizeof(Sample) * ip->samples); lp->size += sizeof(Sample) * ip->samples; ip->left_samples = ip->samples; ip->left_sample = ip->sample; right_samples = vlayer_list[vlayer][3]; ip->right_samples = right_samples; if (right_samples) { ip->right_sample = (Sample *)safe_malloc(sizeof(Sample) * right_samples); lp->size += sizeof(Sample) * right_samples; stereo_channels = 2; } else ip->right_sample = 0; ip->contents = 0; ctl->cmsg(CMSG_INFO, VERB_NOISY, "%s%s[%d,%d] %s(%d-%d layer %d of %d)", (percussion)? " ":"", name, (percussion)? note_to_use : gm_num, bank, (right_samples)? "(2) " : "", lp->lo, lp->hi, vlayer+1, vlayer_count); for (stereo_layer = 0; stereo_layer < stereo_channels; stereo_layer++) { int sample_count; if (stereo_layer == 0) sample_count = ip->left_samples; else if (stereo_layer == 1) sample_count = ip->right_samples; for (i=0; i < sample_count; i++) { uint8 fractions; int32 tmplong; uint16 tmpshort; uint16 sample_volume; uint8 tmpchar; Sample *sp; uint8 sf2delay; #define READ_CHAR(thing) \ if (1 != fread(&tmpchar, 1, 1, fp)) goto fail; \ thing = tmpchar; #define READ_SHORT(thing) \ if (1 != fread(&tmpshort, 2, 1, fp)) goto fail; \ thing = LE_SHORT(tmpshort); #define READ_LONG(thing) \ if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \ thing = LE_LONG(tmplong); /* * 7 sample name * 1 fractions * 4 length * 4 loop start * 4 loop end * 2 sample rate * 4 low frequency * 4 high frequency * 2 finetune * 1 panning * 6 envelope rates | * 6 envelope offsets | 18 bytes * 3 tremolo sweep, rate, depth | * 3 vibrato sweep, rate, depth | * 1 sample mode * 2 scale frequency * 2 scale factor * 2 sample volume (??) * 34 reserved * Now: 1 delay * 33 reserved */ skip(fp, 7); /* Skip the wave name */ if (1 != fread(&fractions, 1, 1, fp)) { fail: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i); if (stereo_layer == 1) { for (j=0; j<i; j++) free(ip->right_sample[j].data); free(ip->right_sample); i = ip->left_samples; } for (j=0; j<i; j++) free(ip->left_sample[j].data); free(ip->left_sample); free(ip); free(lp); return 0; } if (stereo_layer == 0) sp=&(ip->left_sample[i]); else if (stereo_layer == 1) sp=&(ip->right_sample[i]); READ_LONG(sp->data_length); READ_LONG(sp->loop_start); READ_LONG(sp->loop_end); READ_SHORT(sp->sample_rate); READ_LONG(sp->low_freq); READ_LONG(sp->high_freq); READ_LONG(sp->root_freq); skip(fp, 2); /* Why have a "root frequency" and then "tuning"?? */ READ_CHAR(tmp[0]); if (panning==-1) sp->panning = (tmp[0] * 8 + 4) & 0x7f; else sp->panning=(uint8)(panning & 0x7F); sp->resonance=0; sp->cutoff_freq=0; sp->reverberation=0; sp->chorusdepth=0; sp->exclusiveClass=0; sp->keyToModEnvHold=0; sp->keyToModEnvDecay=0; sp->keyToVolEnvHold=0; sp->keyToVolEnvDecay=0; if (cfg_tuning) { double tune_factor = (double)(cfg_tuning)/1200.0; tune_factor = pow(2.0, tune_factor); sp->root_freq = (uint32)( tune_factor * (double)sp->root_freq ); } /* envelope, tremolo, and vibrato */ if (18 != fread(tmp, 1, 18, fp)) goto fail; if (!tmp[13] || !tmp[14]) { sp->tremolo_sweep_increment= sp->tremolo_phase_increment=sp->tremolo_depth=0; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo"); } else { sp->tremolo_sweep_increment=convert_tremolo_sweep(tmp[12]); sp->tremolo_phase_increment=convert_tremolo_rate(tmp[13]); sp->tremolo_depth=tmp[14]; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * tremolo: sweep %d, phase %d, depth %d", sp->tremolo_sweep_increment, sp->tremolo_phase_increment, sp->tremolo_depth); } if (!tmp[16] || !tmp[17]) { sp->vibrato_sweep_increment= sp->vibrato_control_ratio=sp->vibrato_depth=0; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato"); } else { sp->vibrato_control_ratio=convert_vibrato_rate(tmp[16]); sp->vibrato_sweep_increment= convert_vibrato_sweep(tmp[15], sp->vibrato_control_ratio); sp->vibrato_depth=tmp[17]; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * vibrato: sweep %d, ctl %d, depth %d", sp->vibrato_sweep_increment, sp->vibrato_control_ratio, sp->vibrato_depth); } READ_CHAR(sp->modes); READ_SHORT(sp->freq_center); READ_SHORT(sp->freq_scale); if (sf2flag) { READ_SHORT(sample_volume); READ_CHAR(sf2delay); READ_CHAR(sp->exclusiveClass); skip(fp, 32); } else { skip(fp, 36); } /* Mark this as a fixed-pitch instrument if such a deed is desired. */ if (note_to_use!=-1) sp->note_to_use=(uint8)(note_to_use); else sp->note_to_use=0; /* seashore.pat in the Midia patch set has no Sustain. I don't understand why, and fixing it by adding the Sustain flag to all looped patches probably breaks something else. We do it anyway. */ if (sp->modes & MODES_LOOPING) sp->modes |= MODES_SUSTAIN; /* Strip any loops and envelopes we're permitted to */ if ((strip_loop==1) && (sp->modes & (MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) { ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain"); sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE); } if (strip_envelope==1) { if (sp->modes & MODES_ENVELOPE) ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope"); sp->modes &= ~MODES_ENVELOPE; } else if (strip_envelope != 0) { /* Have to make a guess. */ if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) { /* No loop? Then what's there to sustain? No envelope needed either... */ sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE); ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - No loop, removing sustain and envelope"); } else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100) { /* Envelope rates all maxed out? Envelope end at a high "offset"? That's a weird envelope. Take it out. */ sp->modes &= ~MODES_ENVELOPE; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Weirdness, removing envelope"); } else if (!(sp->modes & MODES_SUSTAIN)) { /* No sustain? Then no envelope. I don't know if this is justified, but patches without sustain usually don't need the envelope either... at least the Gravis ones. They're mostly drums. I think. */ sp->modes &= ~MODES_ENVELOPE; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - No sustain, removing envelope"); } } sp->attenuation = 0; for (j=ATTACK; j<DELAY; j++) { sp->envelope_rate[j]= (j<3)? convert_envelope_rate_attack(tmp[j], 11) : convert_envelope_rate(tmp[j]); sp->envelope_offset[j]= convert_envelope_offset(tmp[6+j]); } if (sf2flag) { if (sf2delay > 5) sf2delay = 5; sp->envelope_rate[DELAY] = (int32)( (sf2delay*play_mode->rate) / 1000 ); } else { sp->envelope_rate[DELAY]=0; } sp->envelope_offset[DELAY]=0; for (j=ATTACK; j<DELAY; j++) { sp->modulation_rate[j]=sp->envelope_rate[j]; sp->modulation_offset[j]=sp->envelope_offset[j]; } sp->modulation_rate[DELAY] = sp->modulation_offset[DELAY] = 0; sp->modEnvToFilterFc=0; sp->modEnvToPitch=0; sp->lfo_sweep_increment = 0; sp->lfo_phase_increment = 0; sp->modLfoToFilterFc = 0; sp->vibrato_delay = 0; /* Then read the sample data */ if (sp->data_length/2 > MAX_SAMPLE_SIZE) { goto fail; } sp->data = safe_malloc(sp->data_length + 1); lp->size += sp->data_length + 1; if (1 != fread(sp->data, sp->data_length, 1, fp)) goto fail; if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */ { int32 i=sp->data_length; uint8 *cp=(uint8 *)(sp->data); uint16 *tmp,*newdta; tmp=newdta=safe_malloc(sp->data_length*2 + 2); while (i--) *tmp++ = (uint16)(*cp++) << 8; cp=(uint8 *)(sp->data); sp->data = (sample_t *)newdta; free(cp); sp->data_length *= 2; sp->loop_start *= 2; sp->loop_end *= 2; } #ifndef LITTLE_ENDIAN else /* convert to machine byte order */ { int32 i=sp->data_length/2; int16 *tmp=(int16 *)sp->data,s; while (i--) { s=LE_SHORT(*tmp); *tmp++=s; } } #endif if (sp->modes & MODES_UNSIGNED) /* convert to signed data */ { int32 i=sp->data_length/2; int16 *tmp=(int16 *)sp->data; while (i--) *tmp++ ^= 0x8000; } /* Reverse reverse loops and pass them off as normal loops */ if (sp->modes & MODES_REVERSE) { int32 t; /* The GUS apparently plays reverse loops by reversing the whole sample. We do the same because the GUS does not SUCK. */ ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s", name); reverse_data((int16 *)sp->data, 0, sp->data_length/2); t=sp->loop_start; sp->loop_start=sp->data_length - sp->loop_end; sp->loop_end=sp->data_length - t; sp->modes &= ~MODES_REVERSE; sp->modes |= MODES_LOOPING; /* just in case */ } /* If necessary do some anti-aliasing filtering */ if (antialiasing_allowed) antialiasing(sp,play_mode->rate); #ifdef ADJUST_SAMPLE_VOLUMES if (amp!=-1) sp->volume=(FLOAT_T)((amp) / 100.0); else if (sf2flag) sp->volume=(FLOAT_T)((sample_volume) / 255.0); else { /* Try to determine a volume scaling factor for the sample. This is a very crude adjustment, but things sound more balanced with it. Still, this should be a runtime option. */ uint32 i, numsamps=sp->data_length/2; uint32 higher=0, highcount=0; int16 maxamp=0,a; int16 *tmp=(int16 *)sp->data; i = numsamps; while (i--) { a=*tmp++; if (a<0) a=-a; if (a>maxamp) maxamp=a; } tmp=(int16 *)sp->data; i = numsamps; while (i--) { a=*tmp++; if (a<0) a=-a; if (a > 3*maxamp/4) { higher += a; highcount++; } } if (highcount) higher /= highcount; else higher = 10000; sp->volume = (32768.0 * 0.875) / (double)higher ; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f", sp->volume); } #else if (amp!=-1) sp->volume=(double)(amp) / 100.0; else sp->volume=1.0; #endif sp->data_length /= 2; /* These are in bytes. Convert into samples. */ sp->loop_start /= 2; sp->loop_end /= 2; sp->data[sp->data_length] = sp->data[sp->data_length-1]; /* Then fractional samples */ sp->data_length <<= FRACTION_BITS; sp->loop_start <<= FRACTION_BITS; sp->loop_end <<= FRACTION_BITS; /* trim off zero data at end */ { int ls = sp->loop_start>>FRACTION_BITS; int le = sp->loop_end>>FRACTION_BITS; int se = sp->data_length>>FRACTION_BITS; while (se > 1 && !sp->data[se-1]) se--; if (le > se) le = se; if (ls >= le) sp->modes &= ~MODES_LOOPING; sp->loop_end = le<<FRACTION_BITS; sp->data_length = se<<FRACTION_BITS; } /* Adjust for fractional loop points. This is a guess. Does anyone know what "fractions" really stands for? */ sp->loop_start |= (fractions & 0x0F) << (FRACTION_BITS-4); sp->loop_end |= ((fractions>>4) & 0x0F) << (FRACTION_BITS-4); /* If this instrument will always be played on the same note, and it's not looped, we can resample it now. */ if (sp->note_to_use && !(sp->modes & MODES_LOOPING)) pre_resample(sp); #ifdef LOOKUP_HACK /* Squash the 16-bit data into 8 bits. */ { uint8 *gulp,*ulp; int16 *swp; int l=sp->data_length >> FRACTION_BITS; gulp=ulp=safe_malloc(l+1); swp=(int16 *)sp->data; while(l--) *ulp++ = (*swp++ >> 8) & 0xFF; free(sp->data); sp->data=(sample_t *)gulp; } #endif if (strip_tail==1) { /* Let's not really, just say we did. */ ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail"); sp->data_length = sp->loop_end; } } /* end of sample loop */ } /* end of stereo layer loop */ } /* end of vlayer loop */ close_file(fp); return headlp; }
/* If panning or note_to_use != -1, it will be used for all samples, instead of the sample-specific values in the instrument file. For note_to_use, any value <0 or >127 will be forced to 0. For other parameters, 1 means yes, 0 means no, other values are undefined. TODO: do reverse loops right */ static Instrument *load_instrument(Renderer *song, const char *name, int percussion, int panning, int note_to_use, int strip_loop, int strip_envelope, int strip_tail) { Instrument *ip; Sample *sp; FileReader *fp; GF1PatchHeader header; GF1InstrumentData idata; GF1LayerData layer_data; GF1PatchData patch_data; int i, j; bool noluck = false; if (!name) return 0; /* Open patch file */ if ((fp = pathExpander.openFileReader(name, NULL)) == NULL) { /* Try with various extensions */ FString tmp = name; tmp += ".pat"; if ((fp = pathExpander.openFileReader(tmp, NULL)) == NULL) { #ifdef __unix__ // Windows isn't case-sensitive. tmp.ToUpper(); if ((fp = pathExpander.openFileReader(tmp, NULL)) == NULL) #endif { noluck = true; } } } if (noluck) { cmsg(CMSG_ERROR, VERB_NORMAL, "Instrument `%s' can't be found.\n", name); return 0; } cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s\n", name); /* Read some headers and do cursory sanity checks. */ if (sizeof(header) != fp->Read(&header, sizeof(header))) { failread: cmsg(CMSG_ERROR, VERB_NORMAL, "%s: Error reading instrument.\n", name); delete fp; return 0; } if (strncmp(header.Header, GF1_HEADER_TEXT, HEADER_SIZE - 4) != 0) { cmsg(CMSG_ERROR, VERB_NORMAL, "%s: Not an instrument.\n", name); delete fp; return 0; } if (strcmp(header.Header + 8, "110") < 0) { cmsg(CMSG_ERROR, VERB_NORMAL, "%s: Is an old and unsupported patch version.\n", name); delete fp; return 0; } if (sizeof(idata) != fp->Read(&idata, sizeof(idata))) { goto failread; } header.WaveForms = LittleShort(header.WaveForms); header.MasterVolume = LittleShort(header.MasterVolume); header.DataSize = LittleLong(header.DataSize); idata.Instrument = LittleShort(idata.Instrument); if (header.Instruments != 1 && header.Instruments != 0) /* instruments. To some patch makers, 0 means 1 */ { cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle patches with %d instruments.\n", header.Instruments); delete fp; return 0; } if (idata.Layers != 1 && idata.Layers != 0) /* layers. What's a layer? */ { cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle instruments with %d layers.\n", idata.Layers); delete fp; return 0; } if (sizeof(layer_data) != fp->Read(&layer_data, sizeof(layer_data))) { goto failread; } if (layer_data.Samples == 0) { cmsg(CMSG_ERROR, VERB_NORMAL, "Instrument has 0 samples.\n"); delete fp; return 0; } ip = new Instrument; ip->samples = layer_data.Samples; ip->sample = (Sample *)safe_malloc(sizeof(Sample) * layer_data.Samples); memset(ip->sample, 0, sizeof(Sample) * layer_data.Samples); for (i = 0; i < layer_data.Samples; ++i) { if (sizeof(patch_data) != fp->Read(&patch_data, sizeof(patch_data))) { fail: cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d.\n", i); delete ip; delete fp; return 0; } sp = &(ip->sample[i]); sp->data_length = LittleLong(patch_data.WaveSize); sp->loop_start = LittleLong(patch_data.StartLoop); sp->loop_end = LittleLong(patch_data.EndLoop); sp->sample_rate = LittleShort(patch_data.SampleRate); sp->low_freq = float(LittleLong(patch_data.LowFrequency)); sp->high_freq = float(LittleLong(patch_data.HighFrequency)) + 0.9999f; sp->root_freq = float(LittleLong(patch_data.RootFrequency)); sp->high_vel = 127; sp->velocity = -1; sp->type = INST_GUS; // Expand to SF2 range. if (panning == -1) { sp->panning = (patch_data.Balance & 0x0F) * 1000 / 15 - 500; } else { sp->panning = (panning & 0x7f) * 1000 / 127 - 500; } song->compute_pan((sp->panning + 500) / 1000.0, INST_GUS, sp->left_offset, sp->right_offset); /* tremolo */ if (patch_data.TremoloRate == 0 || patch_data.TremoloDepth == 0) { sp->tremolo_sweep_increment = 0; sp->tremolo_phase_increment = 0; sp->tremolo_depth = 0; cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo\n"); } else { sp->tremolo_sweep_increment = convert_tremolo_sweep(song, patch_data.TremoloSweep); sp->tremolo_phase_increment = convert_tremolo_rate(song, patch_data.TremoloRate); sp->tremolo_depth = patch_data.TremoloDepth; cmsg(CMSG_INFO, VERB_DEBUG, " * tremolo: sweep %d, phase %d, depth %d\n", sp->tremolo_sweep_increment, sp->tremolo_phase_increment, sp->tremolo_depth); } /* vibrato */ if (patch_data.VibratoRate == 0 || patch_data.VibratoDepth == 0) { sp->vibrato_sweep_increment = 0; sp->vibrato_control_ratio = 0; sp->vibrato_depth = 0; cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato\n"); } else { sp->vibrato_control_ratio = convert_vibrato_rate(song, patch_data.VibratoRate); sp->vibrato_sweep_increment = convert_vibrato_sweep(song, patch_data.VibratoSweep, sp->vibrato_control_ratio); sp->vibrato_depth = patch_data.VibratoDepth; cmsg(CMSG_INFO, VERB_DEBUG, " * vibrato: sweep %d, ctl %d, depth %d\n", sp->vibrato_sweep_increment, sp->vibrato_control_ratio, sp->vibrato_depth); } sp->modes = patch_data.Modes; /* Mark this as a fixed-pitch instrument if such a deed is desired. */ if (note_to_use != -1) { sp->scale_note = note_to_use; sp->scale_factor = 0; } else { sp->scale_note = LittleShort(patch_data.ScaleFrequency); sp->scale_factor = LittleShort(patch_data.ScaleFactor); if (sp->scale_factor <= 2) { sp->scale_factor *= 1024; } else if (sp->scale_factor > 2048) { sp->scale_factor = 1024; } if (sp->scale_factor != 1024) { cmsg(CMSG_INFO, VERB_DEBUG, " * Scale: note %d, factor %d\n", sp->scale_note, sp->scale_factor); } } #if 0 /* seashore.pat in the Midia patch set has no Sustain. I don't understand why, and fixing it by adding the Sustain flag to all looped patches probably breaks something else. We do it anyway. */ if (sp->modes & PATCH_LOOPEN) { sp->modes |= PATCH_SUSTAIN; } #endif /* [RH] Alas, eawpats has percussion instruments with bad envelopes. :( * (See cymchina.pat for one example of this sadness.) * Do this logic for instruments without a description, only. Hopefully that * catches all the patches that need it without including any extra. */ for (j = 0; j < DESC_SIZE; ++j) { if (header.Description[j] != 0) break; } /* Strip any loops and envelopes we're permitted to */ /* [RH] (But PATCH_BACKWARD isn't a loop flag at all!) */ if ((strip_loop == 1) && (sp->modes & (PATCH_SUSTAIN | PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD))) { cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain\n"); if (j == DESC_SIZE) { sp->modes &= ~(PATCH_SUSTAIN | PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD); } } if (strip_envelope == 1) { cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope\n"); /* [RH] The envelope isn't really removed, but this is the way the standard * Gravis patches get that effect: All rates at maximum, and all offsets at * a constant level. */ if (j == DESC_SIZE) { int k; for (k = 1; k < ENVELOPES; ++k) { /* Find highest offset. */ if (patch_data.EnvelopeOffset[k] > patch_data.EnvelopeOffset[0]) { patch_data.EnvelopeOffset[0] = patch_data.EnvelopeOffset[k]; } } for (k = 0; k < ENVELOPES; ++k) { patch_data.EnvelopeRate[k] = 63; patch_data.EnvelopeOffset[k] = patch_data.EnvelopeOffset[0]; } } } for (j = 0; j < 6; j++) { sp->envelope.gf1.rate[j] = patch_data.EnvelopeRate[j]; /* [RH] GF1NEW clamps the offsets to the range [5,251], so we do too. */ sp->envelope.gf1.offset[j] = clamp<BYTE>(patch_data.EnvelopeOffset[j], 5, 251); } /* Then read the sample data */ if (((sp->modes & PATCH_16) && sp->data_length/2 > MAX_SAMPLE_SIZE) || (!(sp->modes & PATCH_16) && sp->data_length > MAX_SAMPLE_SIZE)) { goto fail; } sp->data = (sample_t *)safe_malloc(sp->data_length); if (sp->data_length != fp->Read(sp->data, sp->data_length)) goto fail; convert_sample_data(sp, sp->data); /* Reverse reverse loops and pass them off as normal loops */ if (sp->modes & PATCH_BACKWARD) { int t; /* The GUS apparently plays reverse loops by reversing the whole sample. We do the same because the GUS does not SUCK. */ cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s\n", name); reverse_data((sample_t *)sp->data, 0, sp->data_length); sp->data[sp->data_length] = sp->data[sp->data_length - 1]; t = sp->loop_start; sp->loop_start = sp->data_length - sp->loop_end; sp->loop_end = sp->data_length - t; sp->modes &= ~PATCH_BACKWARD; sp->modes |= PATCH_LOOPEN; /* just in case */ } /* Then fractional samples */ sp->data_length <<= FRACTION_BITS; sp->loop_start <<= FRACTION_BITS; sp->loop_end <<= FRACTION_BITS; /* Adjust for fractional loop points. */ sp->loop_start |= (patch_data.Fractions & 0x0F) << (FRACTION_BITS-4); sp->loop_end |= (patch_data.Fractions & 0xF0) << (FRACTION_BITS-4-4); /* If this instrument will always be played on the same note, and it's not looped, we can resample it now. */ if (sp->scale_factor == 0 && !(sp->modes & PATCH_LOOPEN)) { pre_resample(song, sp); } if (strip_tail == 1) { /* Let's not really, just say we did. */ cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail\n"); sp->data_length = sp->loop_end; } } delete fp; return ip; }
/* If panning or note_to_use != -1, it will be used for all samples, instead of the sample-specific values in the instrument file. For note_to_use, any value <0 or >127 will be forced to 0. For other parameters, 1 means yes, 0 means no, other values are undefined. TODO: do reverse loops right */ static Instrument *load_instrument(char *name, int percussion, int panning, int amp, int note_to_use, int strip_loop, int strip_envelope, int strip_tail) { ignore_unused_variable_warning(percussion); Instrument *ip; Sample *sp; FILE *fp; uint8 tmp[1024]; int i,j,noluck=0; #ifdef PATCH_EXT_LIST static const char *patch_ext[] = PATCH_EXT_LIST; #endif if (!name) return 0; /* Open patch file */ if ((fp=open_file(name, 1, OF_NORMAL)) == NULL) { noluck=1; #ifdef PATCH_EXT_LIST /* Try with various extensions */ for (i=0; patch_ext[i]; i++) { if (strlen(name)+strlen(patch_ext[i])<1024) { char path[1024]; strcpy(path, name); strcat(path, patch_ext[i]); if ((fp=open_file(path, 1, OF_NORMAL)) != NULL) { noluck=0; break; } } } #endif } if (noluck) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Instrument `%s' can't be found.", name); return 0; } ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename); /* Read some headers and do cursory sanity checks. There are loads of magic offsets. This could be rewritten... */ if ((239 != fread(tmp, 1, 239, fp)) || (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) && memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the differences are */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name); return 0; } if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers, 0 means 1 */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle patches with %d instruments", tmp[82]); return 0; } if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle instruments with %d layers", tmp[151]); return 0; } ip=safe_Malloc<Instrument>(); ip->samples = tmp[198]; ip->sample = safe_Malloc<Sample>(ip->samples); for (i=0; i<ip->samples; i++) { uint8 fractions; sint32 tmplong; uint16 tmpshort; uint8 tmpchar; #define READ_CHAR(thing) \ if (1 != fread(&tmpchar, 1, 1, fp)) goto fail; \ thing = tmpchar; #define READ_SHORT(thing) \ if (1 != fread(&tmpshort, 2, 1, fp)) goto fail; \ thing = LE_SHORT(tmpshort); #define READ_LONG(thing) \ if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \ thing = LE_LONG(tmplong); skip(fp, 7); /* Skip the wave name */ if (1 != fread(&fractions, 1, 1, fp)) { fail: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i); for (j=0; j<i; j++) free(ip->sample[j].data); free(ip->sample); free(ip); return 0; } sp=&(ip->sample[i]); READ_LONG(sp->data_length); READ_LONG(sp->loop_start); READ_LONG(sp->loop_end); READ_SHORT(sp->sample_rate); READ_LONG(sp->low_freq); READ_LONG(sp->high_freq); READ_LONG(sp->root_freq); skip(fp, 2); /* Why have a "root frequency" and then "tuning"?? */ READ_CHAR(tmp[0]); if (panning==-1) sp->panning = (tmp[0] * 8 + 4) & 0x7f; else sp->panning=static_cast<uint8>(panning & 0x7F); /* envelope, tremolo, and vibrato */ if (18 != fread(tmp, 1, 18, fp)) goto fail; if (!tmp[13] || !tmp[14]) { sp->tremolo_sweep_increment= sp->tremolo_phase_increment=sp->tremolo_depth=0; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo"); } else { sp->tremolo_sweep_increment=convert_tremolo_sweep(tmp[12]); sp->tremolo_phase_increment=convert_tremolo_rate(tmp[13]); sp->tremolo_depth=tmp[14]; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * tremolo: sweep %d, phase %d, depth %d", sp->tremolo_sweep_increment, sp->tremolo_phase_increment, sp->tremolo_depth); } if (!tmp[16] || !tmp[17]) { sp->vibrato_sweep_increment= sp->vibrato_control_ratio=sp->vibrato_depth=0; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato"); } else { sp->vibrato_control_ratio=convert_vibrato_rate(tmp[16]); sp->vibrato_sweep_increment= convert_vibrato_sweep(tmp[15], sp->vibrato_control_ratio); sp->vibrato_depth=tmp[17]; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * vibrato: sweep %d, ctl %d, depth %d", sp->vibrato_sweep_increment, sp->vibrato_control_ratio, sp->vibrato_depth); } READ_CHAR(sp->modes); skip(fp, 40); /* skip the useless scale frequency, scale factor (what's it mean?), and reserved space */ /* Mark this as a fixed-pitch instrument if such a deed is desired. */ if (note_to_use!=-1) sp->note_to_use=static_cast<uint8>(note_to_use); else sp->note_to_use=0; /* seashore.pat in the Midia patch set has no Sustain. I don't understand why, and fixing it by adding the Sustain flag to all looped patches probably breaks something else. We do it anyway. */ if (sp->modes & MODES_LOOPING) sp->modes |= MODES_SUSTAIN; /* Strip any loops and envelopes we're permitted to */ if ((strip_loop==1) && (sp->modes & (MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) { ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain"); sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE); } if (strip_envelope==1) { if (sp->modes & MODES_ENVELOPE) ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope"); sp->modes &= ~MODES_ENVELOPE; } else if (strip_envelope != 0) { /* Have to make a guess. */ if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) { /* No loop? Then what's there to sustain? No envelope needed either... */ sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE); ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - No loop, removing sustain and envelope"); } else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100) { /* Envelope rates all maxed out? Envelope end at a high "offset"? That's a weird envelope. Take it out. */ sp->modes &= ~MODES_ENVELOPE; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Weirdness, removing envelope"); } else if (!(sp->modes & MODES_SUSTAIN)) { /* No sustain? Then no envelope. I don't know if this is justified, but patches without sustain usually don't need the envelope either... at least the Gravis ones. They're mostly drums. I think. */ sp->modes &= ~MODES_ENVELOPE; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - No sustain, removing envelope"); } } for (j=0; j<6; j++) { sp->envelope_rate[j]= convert_envelope_rate(tmp[j]); sp->envelope_offset[j]= convert_envelope_offset(tmp[6+j]); } /* Then read the sample data */ sp->data = safe_Malloc<sample_t>(sp->data_length); if (1 != fread(sp->data, sp->data_length, 1, fp)) goto fail; if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */ { sint32 i=sp->data_length; uint8 *cp=reinterpret_cast<uint8 *>(sp->data); uint16 *tmp,*new_dat; tmp=new_dat=safe_Malloc<uint16>(sp->data_length); while (i--) *tmp++ = static_cast<uint16>(*cp++) << 8; cp=reinterpret_cast<uint8 *>(sp->data); sp->data = reinterpret_cast<sample_t *>(new_dat); free(cp); sp->data_length *= 2; sp->loop_start *= 2; sp->loop_end *= 2; } #ifndef TIMIDITY_LITTLE_ENDIAN else /* convert to machine byte order */ { sint32 i=sp->data_length/2; sint16 *tmp=reinterpret_cast<sint16 *>(sp->data),s; while (i--) { s=LE_SHORT(*tmp); *tmp++=s; } } #endif if (sp->modes & MODES_UNSIGNED) /* convert to signed data */ { sint32 i=sp->data_length/2; sint16 *tmp = sp->data; while (i--) *tmp++ ^= 0x8000; } /* Reverse reverse loops and pass them off as normal loops */ if (sp->modes & MODES_REVERSE) { sint32 t; /* The GUS apparently plays reverse loops by reversing the whole sample. We do the same because the GUS does not SUCK. */ ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s", name); reverse_data(sp->data, 0, sp->data_length/2); t=sp->loop_start; sp->loop_start=sp->data_length - sp->loop_end; sp->loop_end=sp->data_length - t; sp->modes &= ~MODES_REVERSE; sp->modes |= MODES_LOOPING; /* just in case */ } /* If necessary do some anti-aliasing filtering */ if (antialiasing_allowed) antialiasing(sp,play_mode->rate); #ifdef ADJUST_SAMPLE_VOLUMES if (amp!=-1) sp->volume=static_cast<float>((amp) / 100.0); else { /* Try to determine a volume scaling factor for the sample. This is a very crude adjustment, but things sound more balanced with it. Still, this should be a runtime option. */ sint32 i=sp->data_length/2; sint16 maxamp=0,a; sint16 *tmp = sp->data; while (i--) { a=*tmp++; if (a<0) a=-a; if (a>maxamp) maxamp=a; } sp->volume=static_cast<float>(32768.0 / maxamp); ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f", sp->volume); } #else if (amp!=-1) sp->volume=static_cast<double>(amp) / 100.0; else sp->volume=1.0; #endif sp->data_length /= 2; /* These are in bytes. Convert into samples. */ sp->loop_start /= 2; sp->loop_end /= 2; /* Then fractional samples */ sp->data_length <<= FRACTION_BITS; sp->loop_start <<= FRACTION_BITS; sp->loop_end <<= FRACTION_BITS; /* Adjust for fractional loop points. This is a guess. Does anyone know what "fractions" really stands for? */ sp->loop_start |= (fractions & 0x0F) << (FRACTION_BITS-4); sp->loop_end |= ((fractions>>4) & 0x0F) << (FRACTION_BITS-4); /* If this instrument will always be played on the same note, and it's not looped, we can resample it now. */ if (sp->note_to_use && !(sp->modes & MODES_LOOPING)) pre_resample(sp); #ifdef LOOKUP_HACK /* Squash the 16-bit data into 8 bits. */ { uint8 *gulp,*ulp; sint16 *swp; int l=sp->data_length >> FRACTION_BITS; gulp=ulp=safe_Malloc<uint8>(l+1); swp=(sint16 *)sp->data; while(l--) *ulp++ = (*swp++ >> 8) & 0xFF; free(sp->data); sp->data=(sample_t *)gulp; } #endif if (strip_tail==1) { /* Let's not really, just say we did. */ ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail"); sp->data_length = sp->loop_end; } } close_file(fp); return ip; }