timidity_instrum.cpp

Go to the documentation of this file.
00001 /*
00002 
00003     TiMidity -- Experimental MIDI to WAVE converter
00004     Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 
00020    instrum.c 
00021    
00022    Code to load and unload GUS-compatible instrument patches.
00023 
00024 */
00025 
00026 #include "pent_include.h"
00027 
00028 #ifdef USE_TIMIDITY_MIDI
00029 
00030 #include <cstdio>
00031 #include <cstring>
00032 #include <cstdlib>
00033 
00034 #include "timidity.h"
00035 #include "timidity_common.h"
00036 #include "timidity_instrum.h"
00037 #include "timidity_playmidi.h"
00038 #include "timidity_output.h"
00039 #include "timidity_controls.h"
00040 #include "timidity_resample.h"
00041 #include "timidity_tables.h"
00042 #include "timidity_filter.h"
00043 
00044 #ifdef NS_TIMIDITY
00045 namespace NS_TIMIDITY {
00046 #endif
00047 
00048 /* Some functions get aggravated if not even the standard banks are 
00049    available. */
00050 static ToneBank standard_tonebank, standard_drumset;
00051 ToneBank 
00052   *tonebank[128]={&standard_tonebank},
00053   *drumset[128]={&standard_drumset};
00054 
00055 /* This is a special instrument, used for all melodic programs */
00056 Instrument *default_instrument=0;
00057 
00058 /* This is only used for tracks that don't specify a program */
00059 int default_program=DEFAULT_PROGRAM;
00060 
00061 int antialiasing_allowed=0;
00062 #ifdef FAST_DECAY
00063 int fast_decay=1;
00064 #else
00065 int fast_decay=0;
00066 #endif
00067 
00068 static void free_instrument(Instrument *ip)
00069 {
00070   Sample *sp;
00071   int i;
00072   if (!ip) return;
00073   for (i=0; i<ip->samples; i++)
00074     {
00075       sp=&(ip->sample[i]);
00076       free(sp->data);
00077     }
00078   free(ip->sample);
00079   free(ip);
00080 }
00081 
00082 static void free_bank(int dr, int b)
00083 {
00084   int i;
00085   ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
00086   for (i=0; i<128; i++)
00087     if (bank->tone[i].instrument)
00088       {
00089         /* Not that this could ever happen, of course */
00090         if (bank->tone[i].instrument != MAGIC_LOAD_INSTRUMENT)
00091           free_instrument(bank->tone[i].instrument);
00092         bank->tone[i].instrument=0;
00093       }
00094 }
00095 
00096 static sint32 convert_envelope_rate(uint8 rate)
00097 {
00098   sint32 r;
00099 
00100   r=3-((rate>>6) & 0x3);
00101   r*=3;
00102   r = (sint32)(rate & 0x3f) << r; /* 6.9 fixed point */
00103 
00104   /* 15.15 fixed point. */
00105   return (((r * 44100) / play_mode->rate) * control_ratio) 
00106     << ((fast_decay) ? 10 : 9);
00107 }
00108 
00109 static sint32 convert_envelope_offset(uint8 offset)
00110 {
00111   /* This is not too good... Can anyone tell me what these values mean?
00112      Are they GUS-style "exponential" volumes? And what does that mean? */
00113 
00114   /* 15.15 fixed point */
00115   return offset << (7+15);
00116 }
00117 
00118 static sint32 convert_tremolo_sweep(uint8 sweep)
00119 {
00120   if (!sweep)
00121     return 0;
00122 
00123   return
00124     ((control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
00125       (play_mode->rate * sweep);
00126 }
00127 
00128 static sint32 convert_vibrato_sweep(uint8 sweep, sint32 vib_control_ratio)
00129 {
00130   if (!sweep)
00131     return 0;
00132 
00133   return
00134     (sint32) (FSCALE((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT)
00135              / (double)(play_mode->rate * sweep));
00136 
00137   /* this was overflowing with seashore.pat
00138 
00139       ((vib_control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
00140       (play_mode->rate * sweep); */
00141 }
00142 
00143 static sint32 convert_tremolo_rate(uint8 rate)
00144 {
00145   return
00146     ((SINE_CYCLE_LENGTH * control_ratio * rate) << RATE_SHIFT) /
00147       (TREMOLO_RATE_TUNING * play_mode->rate);
00148 }
00149 
00150 static sint32 convert_vibrato_rate(uint8 rate)
00151 {
00152   /* Return a suitable vibrato_control_ratio value */
00153   return
00154     (VIBRATO_RATE_TUNING * play_mode->rate) / 
00155       (rate * 2 * VIBRATO_SAMPLE_INCREMENTS);
00156 }
00157 
00158 static void reverse_data(sint16 *sp, sint32 ls, sint32 le)
00159 {
00160   sint16 s, *ep=sp+le;
00161   sp+=ls;
00162   le-=ls;
00163   le/=2;
00164   while (le--)
00165     {
00166       s=*sp;
00167       *sp++=*ep;
00168       *ep--=s;
00169     }
00170 }
00171 
00172 /* 
00173    If panning or note_to_use != -1, it will be used for all samples,
00174    instead of the sample-specific values in the instrument file. 
00175 
00176    For note_to_use, any value <0 or >127 will be forced to 0.
00177  
00178    For other parameters, 1 means yes, 0 means no, other values are
00179    undefined.
00180 
00181    TODO: do reverse loops right */
00182 static Instrument *load_instrument(char *name, int percussion,
00183                                    int panning, int amp, int note_to_use,
00184                                    int strip_loop, int strip_envelope,
00185                                    int strip_tail)
00186 {
00187   Instrument *ip;
00188   Sample *sp;
00189   FILE *fp;
00190   uint8 tmp[1024];
00191   int i,j,noluck=0;
00192 #ifdef PATCH_EXT_LIST
00193   static char *patch_ext[] = PATCH_EXT_LIST;
00194 #endif
00195 
00196   if (!name) return 0;
00197   
00198   /* Open patch file */
00199   if ((fp=open_file(name, 1, OF_NORMAL)) == NULL)
00200     {
00201       noluck=1;
00202 #ifdef PATCH_EXT_LIST
00203       /* Try with various extensions */
00204       for (i=0; patch_ext[i]; i++)
00205         {
00206           if (strlen(name)+strlen(patch_ext[i])<1024)
00207             {
00208               char path[1024];
00209               strcpy(path, name);
00210               strcat(path, patch_ext[i]);
00211               if ((fp=open_file(path, 1, OF_NORMAL)) != NULL)
00212                 {
00213                   noluck=0;
00214                   break;
00215                 }
00216             }
00217         }
00218 #endif
00219     }
00220   
00221   if (noluck)
00222     {
00223       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
00224                 "Instrument `%s' can't be found.", name);
00225       return 0;
00226     }
00227       
00228   ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename);
00229   
00230   /* Read some headers and do cursory sanity checks. There are loads
00231      of magic offsets. This could be rewritten... */
00232 
00233   if ((239 != fread(tmp, 1, 239, fp)) ||
00234       (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) &&
00235        memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the
00236                                                       differences are */
00237     {
00238       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name);
00239       return 0;
00240     }
00241   
00242   if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers, 
00243                                        0 means 1 */
00244     {
00245       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
00246            "Can't handle patches with %d instruments", tmp[82]);
00247       return 0;
00248     }
00249 
00250   if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */
00251     {
00252       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
00253            "Can't handle instruments with %d layers", tmp[151]);
00254       return 0;
00255     }
00256   
00257   ip=safe_Malloc<Instrument>();
00258   ip->samples = tmp[198];
00259   ip->sample = safe_Malloc<Sample>(ip->samples);
00260   for (i=0; i<ip->samples; i++)
00261     {
00262 
00263       uint8 fractions;
00264       sint32 tmplong;
00265       uint16 tmpshort;
00266       uint8 tmpchar;
00267 
00268 #define READ_CHAR(thing) \
00269       if (1 != fread(&tmpchar, 1, 1, fp)) goto fail; \
00270       thing = tmpchar;
00271 #define READ_SHORT(thing) \
00272       if (1 != fread(&tmpshort, 2, 1, fp)) goto fail; \
00273       thing = LE_SHORT(tmpshort);
00274 #define READ_LONG(thing) \
00275       if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \
00276       thing = LE_LONG(tmplong);
00277 
00278       skip(fp, 7); /* Skip the wave name */
00279 
00280       if (1 != fread(&fractions, 1, 1, fp))
00281         {
00282         fail:
00283           ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i);
00284           for (j=0; j<i; j++)
00285             free(ip->sample[j].data);
00286           free(ip->sample);
00287           free(ip);
00288           return 0;
00289         }
00290 
00291       sp=&(ip->sample[i]);
00292       
00293       READ_LONG(sp->data_length);
00294       READ_LONG(sp->loop_start);
00295       READ_LONG(sp->loop_end);
00296       READ_SHORT(sp->sample_rate);
00297       READ_LONG(sp->low_freq);
00298       READ_LONG(sp->high_freq);
00299       READ_LONG(sp->root_freq);
00300       skip(fp, 2); /* Why have a "root frequency" and then "tuning"?? */
00301       
00302       READ_CHAR(tmp[0]);
00303 
00304       if (panning==-1)
00305         sp->panning = (tmp[0] * 8 + 4) & 0x7f;
00306       else
00307         sp->panning=(uint8)(panning & 0x7F);
00308 
00309       /* envelope, tremolo, and vibrato */
00310       if (18 != fread(tmp, 1, 18, fp)) goto fail; 
00311 
00312       if (!tmp[13] || !tmp[14])
00313         {
00314           sp->tremolo_sweep_increment=
00315             sp->tremolo_phase_increment=sp->tremolo_depth=0;
00316           ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo");
00317         }
00318       else
00319         {
00320           sp->tremolo_sweep_increment=convert_tremolo_sweep(tmp[12]);
00321           sp->tremolo_phase_increment=convert_tremolo_rate(tmp[13]);
00322           sp->tremolo_depth=tmp[14];
00323           ctl->cmsg(CMSG_INFO, VERB_DEBUG,
00324                " * tremolo: sweep %d, phase %d, depth %d",
00325                sp->tremolo_sweep_increment, sp->tremolo_phase_increment,
00326                sp->tremolo_depth);
00327         }
00328 
00329       if (!tmp[16] || !tmp[17])
00330         {
00331           sp->vibrato_sweep_increment=
00332             sp->vibrato_control_ratio=sp->vibrato_depth=0;
00333           ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato");
00334         }
00335       else
00336         {
00337           sp->vibrato_control_ratio=convert_vibrato_rate(tmp[16]);
00338           sp->vibrato_sweep_increment=
00339             convert_vibrato_sweep(tmp[15], sp->vibrato_control_ratio);
00340           sp->vibrato_depth=tmp[17];
00341           ctl->cmsg(CMSG_INFO, VERB_DEBUG,
00342                " * vibrato: sweep %d, ctl %d, depth %d",
00343                sp->vibrato_sweep_increment, sp->vibrato_control_ratio,
00344                sp->vibrato_depth);
00345 
00346         }
00347 
00348       READ_CHAR(sp->modes);
00349 
00350       skip(fp, 40); /* skip the useless scale frequency, scale factor
00351                        (what's it mean?), and reserved space */
00352 
00353       /* Mark this as a fixed-pitch instrument if such a deed is desired. */
00354       if (note_to_use!=-1)
00355         sp->note_to_use=(uint8)(note_to_use);
00356       else
00357         sp->note_to_use=0;
00358       
00359       /* seashore.pat in the Midia patch set has no Sustain. I don't
00360          understand why, and fixing it by adding the Sustain flag to
00361          all looped patches probably breaks something else. We do it
00362          anyway. */
00363          
00364       if (sp->modes & MODES_LOOPING) 
00365         sp->modes |= MODES_SUSTAIN;
00366 
00367       /* Strip any loops and envelopes we're permitted to */
00368       if ((strip_loop==1) && 
00369           (sp->modes & (MODES_SUSTAIN | MODES_LOOPING | 
00370                         MODES_PINGPONG | MODES_REVERSE)))
00371         {
00372           ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain");
00373           sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING | 
00374                         MODES_PINGPONG | MODES_REVERSE);
00375         }
00376 
00377       if (strip_envelope==1)
00378         {
00379           if (sp->modes & MODES_ENVELOPE)
00380             ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope");
00381           sp->modes &= ~MODES_ENVELOPE;
00382         }
00383       else if (strip_envelope != 0)
00384         {
00385           /* Have to make a guess. */
00386           if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE)))
00387             {
00388               /* No loop? Then what's there to sustain? No envelope needed
00389                  either... */
00390               sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE);
00391               ctl->cmsg(CMSG_INFO, VERB_DEBUG, 
00392                         " - No loop, removing sustain and envelope");
00393             }
00394           else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100) 
00395             {
00396               /* Envelope rates all maxed out? Envelope end at a high "offset"?
00397                  That's a weird envelope. Take it out. */
00398               sp->modes &= ~MODES_ENVELOPE;
00399               ctl->cmsg(CMSG_INFO, VERB_DEBUG, 
00400                         " - Weirdness, removing envelope");
00401             }
00402           else if (!(sp->modes & MODES_SUSTAIN))
00403             {
00404               /* No sustain? Then no envelope.  I don't know if this is
00405                  justified, but patches without sustain usually don't need the
00406                  envelope either... at least the Gravis ones. They're mostly
00407                  drums.  I think. */
00408               sp->modes &= ~MODES_ENVELOPE;
00409               ctl->cmsg(CMSG_INFO, VERB_DEBUG, 
00410                         " - No sustain, removing envelope");
00411             }
00412         }
00413 
00414       for (j=0; j<6; j++)
00415         {
00416           sp->envelope_rate[j]=
00417             convert_envelope_rate(tmp[j]);
00418           sp->envelope_offset[j]= 
00419             convert_envelope_offset(tmp[6+j]);
00420         }
00421 
00422       /* Then read the sample data */
00423       sp->data = safe_Malloc<sample_t>(sp->data_length);
00424       if (1 != fread(sp->data, sp->data_length, 1, fp))
00425         goto fail;
00426       
00427       if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */
00428         {
00429           sint32 i=sp->data_length;
00430           uint8 *cp=(uint8 *)(sp->data);
00431           uint16 *tmp,*new_dat;
00432           tmp=new_dat=safe_Malloc<uint16>(sp->data_length);
00433           while (i--)
00434             *tmp++ = (uint16)(*cp++) << 8;
00435           cp=(uint8 *)(sp->data);
00436           sp->data = (sample_t *)new_dat;
00437           free(cp);
00438           sp->data_length *= 2;
00439           sp->loop_start *= 2;
00440           sp->loop_end *= 2;
00441         }
00442 #ifndef LITTLE_ENDIAN
00443       else
00444         /* convert to machine byte order */
00445         {
00446           sint32 i=sp->data_length/2;
00447           sint16 *tmp=(sint16 *)sp->data,s;
00448           while (i--)
00449             { 
00450               s=LE_SHORT(*tmp);
00451               *tmp++=s;
00452             }
00453         }
00454 #endif
00455       
00456       if (sp->modes & MODES_UNSIGNED) /* convert to signed data */
00457         {
00458           sint32 i=sp->data_length/2;
00459           sint16 *tmp=(sint16 *)sp->data;
00460           while (i--)
00461             *tmp++ ^= 0x8000;
00462         }
00463 
00464       /* Reverse reverse loops and pass them off as normal loops */
00465       if (sp->modes & MODES_REVERSE)
00466         {
00467           sint32 t;
00468           /* The GUS apparently plays reverse loops by reversing the
00469              whole sample. We do the same because the GUS does not SUCK. */
00470 
00471           ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s", name);
00472           reverse_data((sint16 *)sp->data, 0, sp->data_length/2);
00473 
00474           t=sp->loop_start;
00475           sp->loop_start=sp->data_length - sp->loop_end;
00476           sp->loop_end=sp->data_length - t;
00477 
00478           sp->modes &= ~MODES_REVERSE;
00479           sp->modes |= MODES_LOOPING; /* just in case */
00480         }
00481 
00482       /* If necessary do some anti-aliasing filtering  */
00483 
00484       if (antialiasing_allowed)
00485           antialiasing(sp,play_mode->rate);
00486 
00487 #ifdef ADJUST_SAMPLE_VOLUMES
00488       if (amp!=-1)
00489         sp->volume=(float)((amp) / 100.0);
00490       else
00491         {
00492           /* Try to determine a volume scaling factor for the sample.
00493              This is a very crude adjustment, but things sound more
00494              balanced with it. Still, this should be a runtime option. */
00495           sint32 i=sp->data_length/2;
00496           sint16 maxamp=0,a;
00497           sint16 *tmp=(sint16 *)sp->data;
00498           while (i--)
00499             {
00500               a=*tmp++;
00501               if (a<0) a=-a;
00502               if (a>maxamp)
00503                 maxamp=a;
00504             }
00505           sp->volume=(float)(32768.0 / maxamp);
00506           ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f", sp->volume);
00507         }
00508 #else
00509       if (amp!=-1)
00510         sp->volume=(double)(amp) / 100.0;
00511       else
00512         sp->volume=1.0;
00513 #endif
00514 
00515       sp->data_length /= 2; /* These are in bytes. Convert into samples. */
00516       sp->loop_start /= 2;
00517       sp->loop_end /= 2;
00518 
00519       /* Then fractional samples */
00520       sp->data_length <<= FRACTION_BITS;
00521       sp->loop_start <<= FRACTION_BITS;
00522       sp->loop_end <<= FRACTION_BITS;
00523 
00524       /* Adjust for fractional loop points. This is a guess. Does anyone
00525          know what "fractions" really stands for? */
00526       sp->loop_start |=
00527         (fractions & 0x0F) << (FRACTION_BITS-4);
00528       sp->loop_end |=
00529         ((fractions>>4) & 0x0F) << (FRACTION_BITS-4);
00530 
00531       /* If this instrument will always be played on the same note,
00532          and it's not looped, we can resample it now. */
00533       if (sp->note_to_use && !(sp->modes & MODES_LOOPING))
00534         pre_resample(sp);
00535 
00536 #ifdef LOOKUP_HACK
00537       /* Squash the 16-bit data into 8 bits. */
00538       {
00539         uint8 *gulp,*ulp;
00540         sint16 *swp;
00541         int l=sp->data_length >> FRACTION_BITS;
00542         gulp=ulp=safe_Malloc<uint8>(l+1);
00543         swp=(sint16 *)sp->data;
00544         while(l--)
00545           *ulp++ = (*swp++ >> 8) & 0xFF;
00546         free(sp->data);
00547         sp->data=(sample_t *)gulp;
00548       }
00549 #endif
00550       
00551       if (strip_tail==1)
00552         {
00553           /* Let's not really, just say we did. */
00554           ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail");
00555           sp->data_length = sp->loop_end;
00556         }
00557     }
00558 
00559   close_file(fp);
00560   return ip;
00561 }
00562 
00563 static int fill_bank(int dr, int b)
00564 {
00565   int i, errors=0;
00566   ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
00567   if (!bank)
00568     {
00569       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
00570            "Huh. Tried to load instruments in non-existent %s %d",
00571            (dr) ? "drumset" : "tone bank", b);
00572       return 0;
00573     }
00574   for (i=0; i<128; i++)
00575     {
00576       if (bank->tone[i].instrument==MAGIC_LOAD_INSTRUMENT)
00577         {
00578           if (!(bank->tone[i].name))
00579             {
00580               ctl->cmsg(CMSG_WARNING, (b!=0) ? VERB_VERBOSE : VERB_NORMAL,
00581                    "No instrument mapped to %s %d, program %d%s",
00582                    (dr)? "drum set" : "tone bank", b, i, 
00583                    (b!=0) ? "" : " - this instrument will not be heard");
00584               if (b!=0)
00585                 {
00586                   /* Mark the corresponding instrument in the default
00587                      bank / drumset for loading (if it isn't already) */
00588                   if (!dr)
00589                     {
00590                       if (!(standard_tonebank.tone[i].instrument))
00591                         standard_tonebank.tone[i].instrument=
00592                           MAGIC_LOAD_INSTRUMENT;
00593                     }
00594                   else
00595                     {
00596                       if (!(standard_drumset.tone[i].instrument))
00597                         standard_drumset.tone[i].instrument=
00598                           MAGIC_LOAD_INSTRUMENT;
00599                     }
00600                 }
00601               bank->tone[i].instrument=0;
00602               errors++;
00603             }
00604           else if (!(bank->tone[i].instrument=
00605                      load_instrument(bank->tone[i].name, 
00606                                      (dr) ? 1 : 0,
00607                                      bank->tone[i].pan,
00608                                      bank->tone[i].amp,
00609                                      (bank->tone[i].note!=-1) ? 
00610                                      bank->tone[i].note :
00611                                      ((dr) ? i : -1),
00612                                      (bank->tone[i].strip_loop!=-1) ?
00613                                      bank->tone[i].strip_loop :
00614                                      ((dr) ? 1 : -1),
00615                                      (bank->tone[i].strip_envelope != -1) ? 
00616                                      bank->tone[i].strip_envelope :
00617                                      ((dr) ? 1 : -1),
00618                                      bank->tone[i].strip_tail )))
00619             {
00620               ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
00621                    "Couldn't load instrument %s (%s %d, program %d)",
00622                    bank->tone[i].name,
00623                    (dr)? "drum set" : "tone bank", b, i);
00624               errors++;
00625             }
00626         }
00627     }
00628   return errors;
00629 }
00630 
00631 int load_missing_instruments(void)
00632 {
00633   int i=128,errors=0;
00634   while (i--)
00635     {
00636       if (tonebank[i])
00637         errors+=fill_bank(0,i);
00638       if (drumset[i])
00639         errors+=fill_bank(1,i);
00640     }
00641   return errors;
00642 }
00643 
00644 void free_instruments(void)
00645 {
00646   int i=128;
00647   while(i--)
00648     {
00649       if (tonebank[i])
00650         free_bank(0,i);
00651       if (drumset[i])
00652         free_bank(1,i);
00653     }
00654 }
00655 
00656 int set_default_instrument(char *name)
00657 {
00658   Instrument *ip;
00659   if (!(ip=load_instrument(name, 0, -1, -1, -1, 0, 0, 0)))
00660     return -1;
00661   if (default_instrument)
00662     free_instrument(default_instrument);
00663   default_instrument=ip;
00664   default_program=SPECIAL_PROGRAM;
00665   return 0;
00666 }
00667 
00668 #ifdef NS_TIMIDITY
00669 };
00670 #endif
00671 
00672 #endif //USE_TIMIDITY_MIDI

Generated on Fri Jul 27 22:27:44 2007 for pentagram by  doxygen 1.4.7