30 #include "gusvoices.h"
35 #include <sys/ioctl.h>
38 #include <sys/param.h>
46 #ifdef HAVE_OSS_SUPPORT
52 unsigned char instruments;
55 unsigned short nr_waveforms;
56 unsigned short master_volume;
57 unsigned long data_size;
62 unsigned char fractions;
66 unsigned short base_freq;
71 unsigned char panning;
73 unsigned char envelope_rate[6];
74 unsigned char envelope_offset[6];
76 unsigned char tremolo_sweep;
77 unsigned char tremolo_rate;
78 unsigned char tremolo_depth;
80 unsigned char vibrato_sweep;
81 unsigned char vibrato_rate;
82 unsigned char vibrato_depth;
86 short scale_frequency;
87 unsigned short scale_factor;
90 int get_dint(
unsigned char *p)
101 unsigned short get_word(
unsigned char *p)
105 for (
int i=0;i<2;i++)
106 v |= (*p++ << (i*8));
121 vm=
new VoiceManager(nvoices);
129 if (delete_GUS_patches_directory)
131 free((
char *)GUS_patches_directory);
132 delete_GUS_patches_directory = 0;
133 GUS_patches_directory=
"/etc";
144 printfdebug(
"ERROR: Could not open /dev/sequencer\n");
148 #ifdef HAVE_OSS_SUPPORT
154 if (ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &device)==-1)
156 printfdebug(
"Error reseting gus samples. Please report\n");
159 totalmemory = device;
160 ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &totalmemory);
162 ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &freememory);
180 #ifdef HAVE_OSS_SUPPORT
183 uchar gm_reset[5]={0x7e, 0x7f, 0x09, 0x01, 0xf7};
184 sysex(gm_reset,
sizeof(gm_reset));
185 for (chn=0;chn<16;chn++)
198 for (
int i = 0; i < nvoices; i++)
200 SEQ_CONTROL(device, i, SEQ_VOLMODE, VOL_METHOD_LINEAR);
201 SEQ_STOP_NOTE(device, i, vm->note(i), 64);
210 if (patchloaded[p]==1)
return p;
211 printfdebug(
"Not loaded %d!\n",p);
213 while ((p<256)&&(patchloaded[p]==0)) p++;
225 if (chn==PERCUSSION_CHANNEL)
227 if (patchloaded[note+128]==0)
return;
229 if (patchloaded[chnpatch[chn]]==0)
return;
231 int v=vm->allocateVoice(chn,note);
233 if (chn==PERCUSSION_CHANNEL)
234 SEQ_SET_PATCH(device,v ,p=
patch(note+128))
236 SEQ_SET_PATCH(device,v ,p=map->
patch(chn,chnpatch[chn]));
237 SEQ_BENDER(device, v, chnbender[chn]);
239 SEQ_START_NOTE(device, v, note, vel);
241 SEQ_CHN_PRESSURE(device, v , chnpressure[chn]);
244 printfdebug(
"Note ON >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel);
251 while ((i=vm->search(chn,note))!=-1)
253 SEQ_STOP_NOTE(device, i, note, vel);
254 vm->deallocateVoice(i);
258 printf(
"Note OFF >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel);
266 while ((i=vm->search(chn,note))!=-1)
267 SEQ_KEY_PRESSURE(device, i, note,vel);
272 if (chn==PERCUSSION_CHANNEL)
return;
275 while ((i=vm->search(chn))!=-1)
276 SEQ_SET_PATCH(device,i,map->
patch(chn,patch));
293 chnbender[chn]=((int)msb<<7) | (lsb & 0x7F);
297 while ((i=vm->search(chn))!=-1)
298 SEQ_BENDER(device, i, chnbender[chn]);
303 if ((ctl==11)||(ctl==7))
305 v=(v*volumepercentage)/100;
311 while ((i=vm->search(chn))!=-1)
312 SEQ_CONTROL(device, i, ctl, v);
314 chncontroller[chn][ctl]=v;
324 if ((dir==NULL)||(dir[0]==0))
return;
325 if (delete_GUS_patches_directory)
326 free((
char *)GUS_patches_directory);
328 GUS_patches_directory = strdup(dir);
329 delete_GUS_patches_directory=1;
332 const char *GUSOut::patchName(
int pgm)
334 return GUS_voice_names[pgm];
340 #ifdef HAVE_OSS_SUPPORT
341 struct pat_header header;
342 struct sample_header sample;
343 if (patchloaded[pgm]==1)
346 printf(
"Trying to reload a patch. This should never happen, please report.\n");
350 if ((patchName(pgm)==NULL)||((patchName(pgm))[0]==0))
353 printf(
"Couldn't guess patch name for patch number %d\n",pgm);
357 char *s=
new char[strlen(GUS_patches_directory)+strlen(patchName(pgm))+10];
358 if (s==NULL)
return -1;
359 sprintf(s,
"%s/%s.pat",GUS_patches_directory,patchName(pgm));
361 printf(
"Loading patch : %s\n",s);
363 struct patch_info *
patch=NULL;
365 if (stat(s, &info)==-1)
368 printf(
"File %s doesn't exist\n",s);
373 FILE *fh=fopen(s,
"rb");
377 printf(
"Couldn't open patch %s\n",s);
382 unsigned char tmp[256];
383 if (fread(tmp,1,0xef,fh)!=0xef)
387 printf(
"Short file ! \n");
391 memcpy ((
char *) &header, tmp,
sizeof (header));
393 if (strncmp(header.magic,
"GF1PATCH110",12)!=0)
396 printf(
"File %s is corrupted or it isn't a patch file\n",s);
400 if (strncmp(header.version,
"ID#000002",10)!=0)
403 printf(
"File %s's version is not supported\n",s);
407 unsigned short nWaves= *(
unsigned short *)&tmp[85];
409 unsigned short masterVolume= *(
unsigned short *)&tmp[87];
410 printf(
"nWaves: %d\n",nWaves);
411 printf(
"masterVolume : %d\n",masterVolume);
416 for (i=0;i<nWaves;i++)
418 fseek(fh,offset,SEEK_SET);
420 if (fread(tmp,1,
sizeof(sample),fh) !=
sizeof(sample))
424 printf(
"Short file\n");
428 memcpy ((
char *) &sample, tmp,
sizeof (sample));
429 sample.fractions = (char)tmp[7];
430 sample.len = get_dint(&tmp[8]);
431 sample.loop_start = get_dint(&tmp[12]);
432 sample.loop_end = get_dint(&tmp[16]);
433 sample.base_freq = get_word(&tmp[20]);
434 sample.low_note = get_dint(&tmp[22]);
435 sample.high_note = get_dint(&tmp[26]);
436 sample.base_note = get_dint(&tmp[30]);
437 sample.detune = (short)get_word(&tmp[34]);
438 sample.panning = (
unsigned char) tmp[36];
440 memcpy (sample.envelope_rate, &tmp[37], 6);
441 memcpy (sample.envelope_offset, &tmp[43], 6);
443 sample.tremolo_sweep = (
unsigned char) tmp[49];
444 sample.tremolo_rate = (
unsigned char) tmp[50];
445 sample.tremolo_depth = (
unsigned char) tmp[51];
447 sample.vibrato_sweep = (
unsigned char) tmp[52];
448 sample.vibrato_rate = (
unsigned char) tmp[53];
449 sample.vibrato_depth = (
unsigned char) tmp[54];
450 sample.modes = (
unsigned char) tmp[55];
451 sample.scale_frequency = (short)get_word(&tmp[56]);
452 sample.scale_factor = get_word(&tmp[58]);
454 offset = offset + 96;
456 patch = (
struct patch_info *) malloc(
sizeof (*patch) + sample.len);
460 printf(
"Not enough memory\n");
464 patch->key = GUS_PATCH;
465 patch->device_no = device;
466 patch->instr_no = pgm;
467 patch->mode = sample.modes | WAVE_TREMOLO | WAVE_VIBRATO | WAVE_SCALE;
468 patch->len = sample.len;
469 patch->loop_start = sample.loop_start;
470 patch->loop_end = sample.loop_end;
471 patch->base_note = sample.base_note;
472 patch->high_note = sample.high_note;
473 patch->low_note = sample.low_note;
474 patch->base_freq = sample.base_freq;
475 patch->detuning = sample.detune;
476 patch->panning = (sample.panning - 7) * 16;
478 memcpy (patch->env_rate, sample.envelope_rate, 6);
479 memcpy (patch->env_offset, sample.envelope_offset, 6);
481 patch->tremolo_sweep = sample.tremolo_sweep;
482 patch->tremolo_rate = sample.tremolo_rate;
483 patch->tremolo_depth = sample.tremolo_depth;
485 patch->vibrato_sweep = sample.vibrato_sweep;
486 patch->vibrato_rate = sample.vibrato_rate;
487 patch->vibrato_depth = sample.vibrato_depth;
489 patch->scale_frequency = sample.scale_frequency;
490 patch->scale_factor = sample.scale_factor;
492 patch->volume = header.master_volume;
494 if (fseek (fh, offset, 0) == -1)
500 if ((
long)fread (patch->data, 1,sample.len,fh) != sample.len)
503 printf (
"Short file\n");
508 SEQ_WRPATCH (patch,
sizeof (*patch) + sample.len);
510 offset = offset + sample.len;
519 ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &freememory);
527 #ifdef HAVE_OSS_SUPPORT
529 for (k=0;k<256;k++) patchloaded[k]=0;
531 int patchesordered[256];
535 patchesLoadingOrder(patchesused,patchesordered);
540 printf(
"Patches used : \n");
543 if (patchesused[k]!=-1) printf(
"%d,",patchesused[k]);
545 printf(
"\n Patches used, sorted :\n");
548 if (patchesordered[k]!=-1) printf(
"%d,",patchesordered[k]);
553 while (patchesordered[i]!=-1)
556 printf(
"Load Patch : %d\n",patchesordered[i]);
564 int compare_decreasing(
const void *a,
const void *b)
571 instr_gm *ai=(instr_gm *)a;
572 instr_gm *bi=(instr_gm *)b;
573 return ai->used<bi->used;
577 void GUSOut::patchesLoadingOrder(
int *patchesused,
int *patchesordered)
585 instr_gm tempmelody[128];
586 instr_gm tempdrums[128];
588 for (i=0,j=128;i<128;i++,j++)
590 tempmelody[i].used=patchesused[i];
592 tempdrums[i].used=patchesused[j];
596 qsort(&tempmelody[0],128,
sizeof(instr_gm),compare_decreasing);
597 qsort(&tempdrums[0],128,
sizeof(instr_gm),compare_decreasing);
607 for (
int k=0;k<128;k++)
609 printf(
"%d - %d\n",tempmelody[k].used,tempmelody[k].pgm);
611 for (
int k=0;k<128;k++)
613 printf(
"%d : %d\n",tempdrums[k].used,tempdrums[k].pgm);
619 while ((i<128)&&(tempmelody[i].used!=0))
626 while ((i<128)&&(tempdrums[i].used!=0))
632 printf(
"Totalmelody : %d,totaldrums : %d\n",totalmelody,totaldrums);
640 if ((tm!=0)&&(td!=0))
642 patchesordered[0]=tempmelody[0].pgm;
643 patchesordered[1]=tempdrums[0].pgm;
647 while ((tm>0)&&(td>0))
651 patchesordered[tgt]=tempdrums[cd].pgm;
657 patchesordered[tgt]=tempmelody[cm].pgm;
666 patchesordered[tgt]=tempmelody[cm].pgm;
673 patchesordered[tgt]=tempdrums[cd].pgm;
682 patchesordered[tgt]=-1;
688 const char *GUSOut::GUS_patches_directory=
"/usr/share/ultrasnd";
690 int GUSOut::delete_GUS_patches_directory = 0;