123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684 |
- /*
- TiMidity -- Experimental MIDI to WAVE converter
- Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- instrum.c
- Code to load and unload GUS-compatible instrument patches.
- */
- #include "../../neo/idlib/precompiled.h"
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include "config.h"
- #include "common.h"
- #include "instrum.h"
- #include "playmidi.h"
- #include "output.h"
- #include "controls.h"
- #include "resample.h"
- #include "tables.h"
- #include "filter.h"
- //void Real_Tim_Free( void *pt );
- /* Some functions get aggravated if not even the standard banks are
- available. */
- static ToneBank standard_tonebank, standard_drumset;
- ToneBank
- *tonebank[128]={&standard_tonebank},
- *drumset[128]={&standard_drumset};
- /* This is a special instrument, used for all melodic programs */
- Instrument *default_instrument=0;
- /* This is only used for tracks that don't specify a program */
- int default_program=DEFAULT_PROGRAM;
- int antialiasing_allowed=0;
- #ifdef FAST_DECAY
- int fast_decay=1;
- #else
- int fast_decay=0;
- #endif
- static void free_instrument(Instrument *ip)
- {
- Sample *sp;
- int i;
- if (!ip) return;
- for (i=0; i<ip->samples; i++)
- {
- sp=&(ip->sample[i]);
- Real_Tim_Free(sp->data);
- }
- Real_Tim_Free(ip->sample);
- Real_Tim_Free(ip);
- }
- static void free_bank(int dr, int b)
- {
- int i;
- ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
- for (i=0; i<128; i++) {
- if (bank->tone[i].instrument)
- {
- /* Not that this could ever happen, of course */
- if (bank->tone[i].instrument != MAGIC_LOAD_INSTRUMENT)
- free_instrument(bank->tone[i].instrument);
- bank->tone[i].instrument=0;
- }
- if (bank->tone[i].name)
- {
- Real_Tim_Free( bank->tone[i].name );
- bank->tone[i].name = NULL;
- }
- }
- }
- static int32_t convert_envelope_rate(uint8_t rate)
- {
- int32_t r;
- r=3-((rate>>6) & 0x3);
- r*=3;
- r = (int32_t)(rate & 0x3f) << r; /* 6.9 fixed point */
- /* 15.15 fixed point. */
- return (((r * 44100) / play_mode->rate) * control_ratio)
- << ((fast_decay) ? 10 : 9);
- }
- static int32_t convert_envelope_offset(uint8_t 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 int32_t convert_tremolo_sweep(uint8_t sweep)
- {
- if (!sweep)
- return 0;
- return
- ((control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
- (play_mode->rate * sweep);
- }
- static int32_t convert_vibrato_sweep(uint8_t sweep, int32_t vib_control_ratio)
- {
- if (!sweep)
- return 0;
- return
- (int32_t) (FSCALE((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT)
- / (double)(play_mode->rate * sweep));
- /* this was overflowing with seashore.pat
- ((vib_control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
- (play_mode->rate * sweep); */
- }
- static int32_t convert_tremolo_rate(uint8_t rate)
- {
- return
- ((SINE_CYCLE_LENGTH * control_ratio * rate) << RATE_SHIFT) /
- (TREMOLO_RATE_TUNING * play_mode->rate);
- }
- static int32_t convert_vibrato_rate(uint8_t rate)
- {
- /* Return a suitable vibrato_control_ratio value */
- return
- (VIBRATO_RATE_TUNING * play_mode->rate) /
- (rate * 2 * VIBRATO_SAMPLE_INCREMENTS);
- }
- static void reverse_data(int16_t *sp, int32_t ls, int32_t le)
- {
- int16_t s, *ep=sp+le;
- sp+=ls;
- le-=ls;
- le/=2;
- while (le--)
- {
- s=*sp;
- *sp++=*ep;
- *ep--=s;
- }
- }
- /*
- 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)
- {
- Instrument *ip;
- Sample *sp;
- idFile * fp;
- uint8_t tmp[1024];
- int i,j,noluck=0;
- char *path;
- char filename[1024];
- #ifdef PATCH_EXT_LIST
- static char *patch_ext[] = PATCH_EXT_LIST;
- #endif
- if (!name) return 0;
- path = "classicmusic/instruments/";
- idStr instName = name;
- instName.ToUpper();
- strcpy( filename, path );
- strcat( filename, instName.c_str() );
- strcat( filename, ".PAT" );
- /* Open patch file */
- if ((fp=open_file(filename, 1, OF_VERBOSE)) == 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)
- {
- strcpy(filename, path);
- strcat(filename, name);
- strcat(filename, patch_ext[i]);
- if ((fp=open_file(filename, 1, OF_VERBOSE)) != 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 != fp->Read(tmp, 239)) ||
- (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=(Instrument *)safe_malloc(sizeof(Instrument));
- ip->samples = tmp[198];
- ip->sample = (Sample *)safe_malloc(sizeof(Sample) * ip->samples);
- for (i=0; i<ip->samples; i++)
- {
- uint8_t fractions;
- int32_t tmplong;
- uint16_t tmpshort;
- uint8_t tmpchar;
- #define READ_CHAR(thing) \
- if (1 != fp->Read(&tmpchar, 1)) goto fail; \
- thing = tmpchar;
- #define READ_SHORT(thing) \
- if (2 != fp->Read(&tmpshort, 2 )) goto fail; \
- thing = LE_SHORT(tmpshort);
- #define READ_LONG(thing) \
- if (4 != fp->Read(&tmplong, 4 )) goto fail; \
- thing = LE_LONG(tmplong);
- skip(fp, 7); /* Skip the wave name */
- if (1 != fp->Read(&fractions, 1 ))
- {
- fail:
- ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i);
- for (j=0; j<i; j++)
- Real_Tim_Free(ip->sample[j].data);
- Real_Tim_Free(ip->sample);
- Real_Tim_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=(uint8)(panning & 0x7F);
- /* envelope, tremolo, and vibrato */
- if (18 != fp->Read(tmp, 18)) 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=(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 = (sample_t*)safe_malloc(sp->data_length);
- if ( static_cast< size_t >( sp->data_length ) != fp->Read(sp->data, sp->data_length ))
- goto fail;
- if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */
- {
- int32_t i=sp->data_length;
- uint8_t *cp=(uint8_t *)(sp->data);
- uint16_t *tmp,*anew;
- tmp=anew=(uint16*)safe_malloc(sp->data_length*2);
- while (i--)
- *tmp++ = (uint16)(*cp++) << 8;
- cp=(uint8_t *)(sp->data);
- sp->data = (sample_t *)anew;
- Real_Tim_Free(cp);
- sp->data_length *= 2;
- sp->loop_start *= 2;
- sp->loop_end *= 2;
- }
- #ifndef LITTLE_ENDIAN
- else
- /* convert to machine byte order */
- {
- int32_t i=sp->data_length/2;
- int16_t *tmp=(int16_t *)sp->data,s;
- while (i--)
- {
- s=LE_SHORT(*tmp);
- *tmp++=s;
- }
- }
- #endif
- if (sp->modes & MODES_UNSIGNED) /* convert to signed data */
- {
- int32_t i=sp->data_length/2;
- int16_t *tmp=(int16_t *)sp->data;
- while (i--)
- *tmp++ ^= 0x8000;
- }
- /* Reverse reverse loops and pass them off as normal loops */
- if (sp->modes & MODES_REVERSE)
- {
- int32_t 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_t *)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)((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. */
- int32_t i=sp->data_length/2;
- int16_t maxamp=0,a;
- int16_t *tmp=(int16_t *)sp->data;
- while (i--)
- {
- a=*tmp++;
- if (a<0) a=-a;
- if (a>maxamp)
- maxamp=a;
- }
- sp->volume=(float)(32768.0 / maxamp);
- 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;
- /* 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_t *gulp,*ulp;
- int16_t *swp;
- int l=sp->data_length >> FRACTION_BITS;
- gulp=ulp=safe_malloc(l+1);
- swp=(int16_t *)sp->data;
- while(l--)
- *ulp++ = (*swp++ >> 8) & 0xFF;
- Real_Tim_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;
- }
- }
- delete fp;
- return ip;
- }
- static int fill_bank(int dr, int b)
- {
- int i, errors=0;
- ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
- if (!bank)
- {
- ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
- "Huh. Tried to load instruments in non-existent %s %d",
- (dr) ? "drumset" : "tone bank", b);
- return 0;
- }
- for (i=0; i<128; i++)
- {
- if (bank->tone[i].instrument==MAGIC_LOAD_INSTRUMENT)
- {
- if (!(bank->tone[i].name))
- {
- ctl->cmsg(CMSG_WARNING, (b!=0) ? VERB_VERBOSE : VERB_NORMAL,
- "No instrument mapped to %s %d, program %d%s",
- (dr)? "drum set" : "tone bank", b, i,
- (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;
- errors++;
- }
- else if (!(bank->tone[i].instrument=
- load_instrument(bank->tone[i].name,
- (dr) ? 1 : 0,
- bank->tone[i].pan,
- bank->tone[i].amp,
- (bank->tone[i].note!=-1) ?
- bank->tone[i].note :
- ((dr) ? i : -1),
- (bank->tone[i].strip_loop!=-1) ?
- bank->tone[i].strip_loop :
- ((dr) ? 1 : -1),
- (bank->tone[i].strip_envelope != -1) ?
- bank->tone[i].strip_envelope :
- ((dr) ? 1 : -1),
- bank->tone[i].strip_tail )))
- {
- ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
- "Couldn't load instrument %s (%s %d, program %d)",
- bank->tone[i].name,
- (dr)? "drum set" : "tone bank", b, i);
- errors++;
- }
- }
- }
- return errors;
- }
- int load_missing_instruments(void)
- {
- int i=128,errors=0;
- while (i--)
- {
- if (tonebank[i])
- errors+=fill_bank(0,i);
- if (drumset[i])
- errors+=fill_bank(1,i);
- }
- return errors;
- }
- void free_instruments(void)
- {
- int i=128;
- while(i--)
- {
- if (tonebank[i])
- free_bank(0,i);
- if (drumset[i])
- free_bank(1,i);
- }
- }
- int set_default_instrument(char *name)
- {
- Instrument *ip;
- if (!(ip=load_instrument(name, 0, -1, -1, -1, 0, 0, 0)))
- return -1;
- if (default_instrument)
- free_instrument(default_instrument);
- default_instrument=ip;
- default_program=SPECIAL_PROGRAM;
- return 0;
- }
|