static void import_ts_check (DATASET *dset) { PRN *prn = gretl_print_new(GRETL_PRINT_STDERR, NULL); int reversed = 0; int mpd = -1; mpd = test_markers_for_dates(dset, &reversed, NULL, prn); if (mpd > 0) { pputs(prn, _("taking date information from row labels\n\n")); if (dset->markers != DAILY_DATE_STRINGS) { dataset_destroy_obs_markers(dset); } if (reversed) { reverse_data(dset, prn); } } #if ODEBUG fprintf(stderr, "xinfo->dset->pd = %d\n", xinfo->dset->pd); #endif if (dset->pd != 1 || strcmp(dset->stobs, "1")) { dset->structure = TIME_SERIES; } gretl_print_destroy(prn); }
/* 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 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(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; }
int gnumeric_get_data (const char *fname, int *list, char *sheetname, DATASET *dset, gretlopt opt, PRN *prn) { int gui = (opt & OPT_G); wbook gbook; wbook *book = &gbook; wsheet gsheet; wsheet *sheet = &gsheet; int sheetnum = -1; int obscol = 0; DATASET *newset; int err = 0; newset = datainfo_new(); if (newset == NULL) { pputs(prn, _("Out of memory\n")); return 1; } wsheet_init(sheet); gretl_push_c_numeric_locale(); if (wbook_get_info(fname, list, sheetname, book, prn)) { pputs(prn, _("Failed to get workbook info")); err = 1; goto getout; } wbook_print_info(book); if (book->nsheets == 0) { pputs(prn, _("No worksheets found")); err = 1; goto getout; } if (gui) { if (book->nsheets > 1) { wsheet_menu(book, 1); sheetnum = book->selected; } else { wsheet_menu(book, 0); sheetnum = 0; } } else { err = wbook_check_params(book); if (err) { gretl_errmsg_set(_("Invalid argument for worksheet import")); } else if (book->selected >= 0) { sheetnum = book->selected; } else { sheetnum = 0; } } if (book->selected == -1) { /* canceled */ err = -1; } if (!err && sheetnum >= 0) { fprintf(stderr, "Getting data...\n"); err = wsheet_setup(sheet, book, sheetnum); if (!err) { err = wsheet_get_data(fname, sheet, &obscol, prn); if (err) { fprintf(stderr, "wsheet_get_data returned %d\n", err); } else { wsheet_print_info(sheet); book->flags |= sheet->flags; } } } if (err) { goto getout; } else { int r0 = 1; /* the first data row */ int i, j, t; int ts_markers = 0; int merge = (dset->Z != NULL); char **ts_S = NULL; int blank_cols = 0; int missvals = 0; int pd = 0; if (obscol) { book_set_obs_labels(book); if (sheet->text_cols == 0) { sheet->text_cols = 1; } } else if (sheet->text_cols > 0) { /* string-valued variable? */ fprintf(stderr, "Problem: sheet->text_cols = %d\n", sheet->text_cols); } if (sheet->colheads == 0) { book_set_auto_varnames(book); r0 = 0; } if (book_numeric_dates(book)) { fputs("found calendar dates in first imported column\n", stderr); } else if (obscol) { fprintf(stderr, "found label strings in first imported column (text_cols = %d)\n", sheet->text_cols); } else if (sheet->text_cols > 0) { fputs("found string-valued variable in first imported column?\n", stderr); } else { fputs("check for label strings in first imported column: not found\n", stderr); } newset->n = sheet->maxrow - sheet->row_offset; if (!sheet->colheads) { pputs(prn, _("it seems there are no variable names\n")); newset->n += 1; } if (book_numeric_dates(book) || obscol) { pd = importer_dates_check(sheet->label + r0, &book->flags, newset, prn, &err); if (pd > 0) { /* got time-series info from dates/labels */ sheet_time_series_setup(sheet, book, newset, pd); ts_markers = newset->markers; ts_S = newset->S; } else if (!book_numeric_dates(book)) { if (labels_are_index(sheet->label, newset->n)) { /* trash the labels */ book_unset_obs_labels(book); } } } newset->v = sheet->maxcol + 2 - sheet->col_offset - sheet->text_cols; fprintf(stderr, "newset->v = %d, newset->n = %d\n", newset->v, newset->n); /* create import dataset */ err = worksheet_start_dataset(newset); if (err) { goto getout; } if (book_time_series(book)) { newset->markers = ts_markers; newset->S = ts_S; } else { dataset_obs_info_default(newset); } j = 1; for (i=1; i<newset->v; i++) { int s = (sheet->colheads)? 1 : 0; int k = i - 1 + sheet->text_cols; double zkt; if (column_is_blank(sheet, k, newset->n)) { blank_cols++; continue; } if (sheet->colheads && *sheet->varname[k] != '\0') { strcpy(newset->varname[j], sheet->varname[k]); } else { sprintf(newset->varname[j], "v%d", j); } for (t=0; t<newset->n; t++) { zkt = sheet->Z[k][s++]; if (zkt == -999 || zkt == -9999) { newset->Z[j][t] = NADBL; } else { newset->Z[j][t] = zkt; } if (na(newset->Z[j][t])) { missvals = 1; } } j++; } if (blank_cols > 0) { fprintf(stderr, "Dropping %d apparently blank column(s)\n", blank_cols); dataset_drop_last_variables(newset, blank_cols); } if (missvals) { pputs(prn, _("Warning: there were missing values\n")); } if (fix_varname_duplicates(newset)) { pputs(prn, _("warning: some variable names were duplicated\n")); } if (book_obs_labels(book) && wsheet_labels_complete(sheet)) { int offset = (sheet->colheads)? 1 : 0; dataset_allocate_obs_markers(newset); if (newset->S != NULL) { for (t=0; t<newset->n; t++) { strcpy(newset->S[t], sheet->label[t+offset]); } } } if (book->flags & BOOK_DATA_REVERSED) { reverse_data(newset, prn); } if (!err && !dataset_is_time_series(newset) && newset->S != NULL) { /* we didn't time series info above, but it's possible the observation strings carry such info */ import_ts_check(newset); } err = merge_or_replace_data(dset, &newset, opt, prn); if (!err && !merge) { dataset_add_import_info(dset, fname, GRETL_GNUMERIC); } if (!err && gui) { wbook_record_params(book, list); } } getout: wbook_free(book); wsheet_free(sheet); gretl_pop_c_numeric_locale(); if (err && newset != NULL) { destroy_dataset(newset); } return err; }