📄 instrum.c
字号:
#ifndef LITTLE_ENDIAN else { /* convert to machine byte order */ int32 i; int16 *tmp = (int16 *) sp->data, s; for (i = 0; i < sp->data_length / 2; i++) s = LE_SHORT(tmp[i]), tmp[i] = 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 loops and pass them off as normal loops */ if (sp->modes & MODES_REVERSE) { /* The GUS apparently plays reverse loops by reversing the * whole sample. We do the same because the GUS does not SUCK. */ int32 t; 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 */ ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s", name); } /* If necessary do some anti-aliasing filtering */ if (antialiasing_allowed) antialiasing((int16 *) sp->data, sp->data_length / 2, sp->sample_rate, play_mode->rate);#ifdef ADJUST_SAMPLE_VOLUMES if (amp != -1) sp->volume = (double) amp / 100; 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. */ int32 i, a, maxamp = 0; int16 *tmp = (int16 *) sp->data; for (i = 0; i < sp->data_length / 2; i++) if ((a = abs(tmp[i])) > maxamp) maxamp = a; sp->volume = 32768 / (double) maxamp; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f", sp->volume); }#else sp->volume = (amp != -1) ? (double) amp / 100 : 1.0;#endif /* These are in bytes. Convert into samples. */ sp->data_length /= 2; sp->loop_start /= 2; sp->loop_end /= 2; /* The sample must be padded out by 2 extra sample, so that * round off errors in the offsets used in interpolation will not * cause a "pop" by reading random data beyond data_length */ sp->data[sp->data_length] = sp->data[sp->data_length + 1] = 0; /* Remove abnormal loops which cause pop noise * in long sustain stage */ if (! (sp->modes & MODES_LOOPING)) { sp->loop_start = sp->data_length - 1; sp->loop_end = sp->data_length; sp->data[sp->data_length - 1] = 0; } /* 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); /* do pitch detection on drums if surround chorus is used */ if (dr && opt_surround_chorus) { sp->chord = -1; sp->root_freq_detected = freq_fourier(sp, &(sp->chord)); sp->transpose_detected = assign_pitch_to_freq(sp->root_freq_detected) - assign_pitch_to_freq(sp->root_freq / 1024.0); }#ifdef LOOKUP_HACK squash_sample_16to8(sp);#endif if (strip_tail == 1) { /* Let's not really, just say we did. */ sp->data_length = sp->loop_end; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail"); } } close_file(tf); store_instrument_cache(ip, name, panning, amp, note_to_use, strip_loop, strip_envelope, strip_tail); return ip;}#ifdef LOOKUP_HACK/*! Squash the 16-bit data into 8 bits. */void squash_sample_16to8(Sample *sp){ uint8 *gulp, *ulp; int16 *swp; int l = sp->data_length >> FRACTION_BITS; gulp = ulp = (uint8 *)safe_malloc(l + 1); swp = (int16 *)sp->data; while (l--) *ulp++ = (*swp++ >> 8) & 0xff; free(sp->data); sp->data = (sample_t *)gulp;}#endifInstrument *load_instrument(int dr, int b, int prog){ ToneBank *bank = ((dr) ? drumset[b] : tonebank[b]); Instrument *ip; int i, font_bank, font_preset, font_keynote; extern Instrument *extract_sample_file(char *); FLOAT_T volume_max; int pan, panning; char infomsg[256]; #ifndef CFG_FOR_SF if (play_system_mode == GS_SYSTEM_MODE && (b == 64 || b == 65)) if (! dr) /* User Instrument */ recompute_userinst(b, prog); else /* User Drumset */ recompute_userdrum(b, prog);#endif if (bank->tone[prog].instype == 1 || bank->tone[prog].instype == 2) { if (bank->tone[prog].instype == 1) { /* Font extention */ font_bank = bank->tone[prog].font_bank; font_preset = bank->tone[prog].font_preset; font_keynote = bank->tone[prog].font_keynote; ip = extract_soundfont(bank->tone[prog].name, font_bank, font_preset, font_keynote); } else /* Sample extension */ ip = extract_sample_file(bank->tone[prog].name); /* amp tuning */ if (ip != NULL && bank->tone[prog].amp != -1) { for (i = 0, volume_max = 0; i < ip->samples; i++) if (volume_max < ip->sample[i].volume) volume_max = ip->sample[i].volume; if (volume_max != 0) for (i = 0; i < ip->samples; i++) ip->sample[i].volume *= bank->tone[prog].amp / 100.0 / volume_max; } /* panning */ if (ip != NULL && bank->tone[prog].pan != -1) { pan = ((int) bank->tone[prog].pan & 0x7f) - 64; for (i = 0; i < ip->samples; i++) { panning = (int) ip->sample[i].panning + pan; panning = (panning < 0) ? 0 : ((panning > 127) ? 127 : panning); ip->sample[i].panning = panning; } } /* note to use */ if (ip != NULL && bank->tone[prog].note != -1) for (i = 0; i < ip->samples; i++) ip->sample[i].root_freq = freq_table[bank->tone[prog].note & 0x7f]; /* filter key-follow */ if (ip != NULL && bank->tone[prog].key_to_fc != 0) for (i = 0; i < ip->samples; i++) ip->sample[i].key_to_fc = bank->tone[prog].key_to_fc; /* filter velocity-follow */ if (ip != NULL && bank->tone[prog].vel_to_fc != 0) for (i = 0; i < ip->samples; i++) ip->sample[i].key_to_fc = bank->tone[prog].vel_to_fc; /* resonance velocity-follow */ if (ip != NULL && bank->tone[prog].vel_to_resonance != 0) for (i = 0; i < ip->samples; i++) ip->sample[i].vel_to_resonance = bank->tone[prog].vel_to_resonance; /* strip tail */ if (ip != NULL && bank->tone[prog].strip_tail == 1) for (i = 0; i < ip->samples; i++) ip->sample[i].data_length = ip->sample[i].loop_end; if (ip != NULL) { i = (dr) ? 0 : prog; if (bank->tone[i].comment) free(bank->tone[i].comment); bank->tone[i].comment = safe_strdup(ip->instname); apply_bank_parameter(ip, &bank->tone[prog]); } return ip; } if (! dr) { font_bank = b; font_preset = prog; font_keynote = -1; } else { font_bank = 128; font_preset = b; font_keynote = prog; } /* preload soundfont */ ip = load_soundfont_inst(0, font_bank, font_preset, font_keynote); if (ip != NULL) { if (bank->tone[prog].comment) free(bank->tone[prog].comment); bank->tone[prog].comment = safe_strdup(ip->instname); } if (ip == NULL) { /* load GUS/patch file */ if (! dr) sprintf(infomsg, "Tonebank %d %d", b, prog + progbase); else sprintf(infomsg, "Drumset %d %d(%s)", b + progbase, prog, note_name[prog % 12]); ip = load_gus_instrument(bank->tone[prog].name, bank, dr, prog, infomsg); if (ip == NULL) { /* no patch; search soundfont again */ ip = load_soundfont_inst(1, font_bank, font_preset, font_keynote); if (ip != NULL) { if (bank->tone[0].comment) free(bank->tone[0].comment); bank->tone[0].comment = safe_strdup(ip->instname); } } } if (ip != NULL) apply_bank_parameter(ip, &bank->tone[prog]); return ip;}static int fill_bank(int dr, int b, int *rc){ int i, errors = 0; ToneBank *bank=((dr) ? drumset[b] : tonebank[b]); if(rc != NULL) *rc = RC_NONE; for(i = 0; i < 128; i++) { if(bank->tone[i].instrument == MAGIC_LOAD_INSTRUMENT) { if(!(bank->tone[i].name)) { bank->tone[i].instrument = load_instrument(dr, b, i); if(bank->tone[i].instrument == NULL) { ctl->cmsg(CMSG_WARNING, (b != 0) ? VERB_VERBOSE : VERB_NORMAL, "No instrument mapped to %s %d, program %d%s", dr ? "drum set" : "tone bank", dr ? b+progbase : b, dr ? i : i+progbase, (b != 0) ? "" : " - this instrument will not be heard"); if(b != 0) { /* Mark the corresponding instrument in the default bank / drumset for loading (if it isn't already) */ if(!dr) { if(!(standard_tonebank.tone[i].instrument)) standard_tonebank.tone[i].instrument = MAGIC_LOAD_INSTRUMENT; } else { if(!(standard_drumset.tone[i].instrument)) standard_drumset.tone[i].instrument = MAGIC_LOAD_INSTRUMENT; } bank->tone[i].instrument = 0; } else bank->tone[i].instrument = MAGIC_ERROR_INSTRUMENT; errors++; } } else { if(rc != NULL) { *rc = check_apply_control(); if(RC_IS_SKIP_FILE(*rc)) return errors; } bank->tone[i].instrument = load_instrument(dr, b, i); if(!bank->tone[i].instrument) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Couldn't load instrument %s " "(%s %d, program %d)", bank->tone[i].name, dr ? "drum set" : "tone bank", dr ? b+progbase : b, dr ? i : i+progbase); errors++; } } } } return errors;}int load_missing_instruments(int *rc){ int i = 128 + map_bank_counter, errors = 0; if(rc != NULL) *rc = RC_NONE; while (i--) { if (tonebank[i]) errors+=fill_bank(0,i,rc); if(rc != NULL && RC_IS_SKIP_FILE(*rc)) return errors; if (drumset[i]) errors+=fill_bank(1,i,rc); if(rc != NULL && RC_IS_SKIP_FILE(*rc)) return errors; } return errors;}static void *safe_memdup(void *s, size_t size){ return memcpy(safe_malloc(size), s, size);}/*! Copy ToneBankElement src to elm. The original elm is released. */void copy_tone_bank_element(ToneBankElement *elm, const ToneBankElement *src){ int i; free_tone_bank_element(elm); memcpy(elm, src, sizeof(ToneBankElement)); if (elm->name) elm->name = safe_strdup(elm->name); if (elm->tunenum) elm->tune = (float *) safe_memdup(elm->tune, elm->tunenum * sizeof(float)); if (elm->envratenum) { elm->envrate = (int **) safe_memdup(elm->envrate, elm->envratenum * sizeof(int *)); for (i = 0; i < elm->envratenum; i++) elm->envrate[i] = (int *) safe_memdup(elm->envrate[i], 6 * sizeof(int)); } if (elm->envofsnum) { elm->envofs = (int **) safe_memdup(elm->envofs, elm->envofsnum * sizeof(int *)); for (i = 0; i < elm->envofsnum; i++) elm->envofs[i] = (int *) safe_memdup(elm->envofs[i], 6 * sizeof(int)); } if (elm->tremnum) { elm->trem = (Quantity **) safe_memdup(elm->trem, elm->tremnum * sizeof(Quantity *)); for (i = 0; i < elm->tremnum; i++) elm->trem[i] = (Quantity *) safe_memdup(elm->trem[i], 3 * sizeof(Quantity)); } if (elm->vibnum) { elm->vib = (Quantity **) safe_memdup(elm->vib, elm->vibnum * sizeof(Quantity *)); for (i = 0; i < elm->vibnum; i++) elm->vib[i] = (Quantity *) safe_memdup(elm->vib[i], 3 * sizeof(Quantity)); } if (elm->sclnotenum) elm->sclnote = (int16 *) safe_memdup(elm->sclnote, elm->sclnotenum * sizeof(int16)); if (elm->scltunenum) elm->scltune = (int16 *) safe_memdup(elm->scltune, elm->scltunenum * sizeof(int16)); if (elm->comment) elm->comment = safe_strdup(elm->comment); if (elm->modenvratenum) { elm->modenvrate = (int **) safe_memdup(elm->modenvrate, elm->modenvratenum * sizeof(int *)); for (i = 0; i < elm->modenvratenum; i++) elm->modenvrate[i] = (int *) safe_memdup(elm->modenvrate[i], 6 * sizeof(int)); } if (elm->modenvofsnum) { elm->modenvofs = (int **) safe_memdup(elm->modenvofs, elm->modenvofsnum * sizeof(int *)); for (i = 0; i < elm->modenvofsnum; i++) elm->modenvofs[i] = (int *) safe_memdup(elm->modenvofs[i], 6 * sizeof(int)); } if (elm->envkeyfnum) { elm->envkeyf = (int **) safe_memdup(elm->envkeyf, elm->envkeyfnum * sizeof(int *)); for (i = 0; i < elm->envkeyfnum; i++) elm->envkeyf[i] = (int *) safe_memdup(elm->envkeyf[i], 6 * sizeof(int)); } if (elm->envvelfnum) { elm->envvelf = (int **) safe_memdup(elm->envvelf, elm->envvelfnum * sizeof(int *)); for (i = 0; i < elm->envvelfnum; i++) elm->envvelf[i] = (int *) safe_memdup(elm->envvelf[i], 6 * sizeof(int)); } if (elm->modenvkeyfnum) { elm->modenvkeyf = (int **) safe_memdup(elm->modenvkeyf, elm->modenvkeyfnum * sizeof(int *)); for (i = 0; i < elm->modenvkeyfnum; i++) elm->modenvkeyf[i] = (int *) safe_memdup(elm->modenvkeyf[i], 6 * sizeof(int)); } if (elm->modenvvelfnum) { elm->modenvvelf = (int **) safe_memdup(elm->modenvvelf, elm->modenvvelfnum * sizeof(int *)); for (i = 0; i < elm->modenvvelfnum; i++) elm->modenvvelf[i] = (int *) safe_memdup(elm->modenvvelf[i], 6 * sizeof(int)); } if (elm->trempitchnum) elm->trempitch = (int16 *) safe_memdup(elm->trempitch, elm->trempitchnum * sizeof(int16)); if (elm->tremfcnum) elm->tremfc = (int16 *) safe_memdup(elm->tremfc, elm->tremfcnum * sizeof(int16)); if (elm->modpitchnum) elm->modpitch = (int16 *) safe_memdup(elm->modpitch, elm->modpitchnum * sizeof(int16)); if (elm->modfcnum) elm->modfc = (int16 *) safe_memdup(elm->modfc, elm->modfcnum * sizeof(int16)); if (elm->fcnum) elm->fc = (int16 *) safe_memdup(elm->fc, elm->fcnum * sizeof(int16)); if (elm->resonum) elm->reso = (int16 *) safe_memdup(elm->reso, elm->resonum * sizeof(int16));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -