32 #include <sys/ioctl.h>
35 #include <sys/param.h>
57 vm =
new VoiceManager (nvoices);
64 if (deleteFMPatchesDirectory)
66 free((
char *)FMPatchesDirectory);
67 deleteFMPatchesDirectory = 0;
68 FMPatchesDirectory=
"/etc";
74 #ifdef HAVE_OSS_SUPPORT
80 printfdebug(
"ERROR: Could not open /dev/sequencer\n");
99 #ifdef HAVE_OSS_SUPPORT
102 uchar gm_reset[5]={0x7e, 0x7f, 0x09, 0x01, 0xf7};
103 sysex(gm_reset,
sizeof(gm_reset));
104 for (chn=0;chn<16;chn++)
116 if (opl==3) ioctl(seqfd, SNDCTL_FM_4OP_ENABLE, &device);
117 SEQ_VOLUME_MODE(device,VOL_METHOD_LINEAR);
119 for (
int i = 0; i < nvoices; i++)
121 SEQ_CONTROL(device, i, SEQ_VOLMODE, VOL_METHOD_LINEAR);
122 SEQ_STOP_NOTE(device, i, vm->note(i), 64);
127 void FMOut::loadFMPatches(
void)
129 #ifdef HAVE_OSS_SUPPORT
130 char patchesfile[strlen(FMPatchesDirectory)+7+1];
131 char drumsfile[strlen(FMPatchesDirectory)+9+1];
133 struct sbi_instrument instr;
136 for ( i=0; i<256; i++ )
138 int stereoeffect=rand()%3;
144 snprintf(patchesfile,
sizeof(patchesfile),
"%s/std.o3",FMPatchesDirectory);
149 snprintf(patchesfile,
sizeof(patchesfile),
"%s/std.sb",FMPatchesDirectory);
152 fh=fopen(patchesfile,
"rb");
153 if (fh==NULL)
return;
157 fread(tmp,size,1,fh);
159 instr.key = ((strncmp(tmp,
"4OP", 3) == 0))? OPL3_PATCH : FM_PATCH;
160 datasize = (strncmp(tmp,
"4OP", 3) == 0)? 22 : 11;
164 tmp[46] = (tmp[46] & 0xcf) | ((++stereoeffect)<<4);
165 stereoeffect=stereoeffect%3;
167 instr.operators[j] = tmp[j+36];
168 SEQ_WRPATCH(&instr,
sizeof(instr));
174 snprintf(drumsfile,
sizeof(drumsfile),
"%s/drums.o3",FMPatchesDirectory);
178 snprintf(drumsfile,
sizeof(drumsfile),
"%s/drums.sb",FMPatchesDirectory);
181 fh=fopen(drumsfile,
"rb");
182 if (fh==NULL)
return;
184 for (i=128;i<175;i++)
186 fread(tmp,size,1,fh);
188 instr.key = (strncmp(tmp,
"4OP", 3) == 0)? OPL3_PATCH : FM_PATCH;
189 datasize = (strncmp(tmp,
"4OP", 3) == 0)? 22 : 11;
193 tmp[46] = (tmp[46] & 0xcf) | ((++stereoeffect)<<4);
194 stereoeffect=stereoeffect%3;
196 instr.operators[j] = tmp[j+36];
197 SEQ_WRPATCH(&instr,
sizeof(instr));
202 printfdebug(
"Patches loaded\n");
209 if (patchloaded[p]==1)
return p;
211 printfdebug(
"Not loaded %d!\n",p);
214 while ((p<256)&&(patchloaded[p]==0)) p++;
226 if (chn==PERCUSSION_CHANNEL)
228 if (patchloaded[note+128]==0)
return;
230 if (patchloaded[chnpatch[chn]]==0)
return;
232 int v=vm->allocateVoice(chn,note);
234 if (chn==PERCUSSION_CHANNEL)
235 SEQ_SET_PATCH(device,v ,p=
patch(note+128))
237 SEQ_SET_PATCH(device,v ,p=map->
patch(chn,chnpatch[chn]));
238 SEQ_BENDER(device, v, chnbender[chn]);
240 SEQ_START_NOTE(device, v, note, vel);
243 SEQ_CHN_PRESSURE(device, v , chnpressure[chn]);
247 printfdebug(
"Note ON >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel);
255 while ((i=vm->search(chn,note))!=-1)
257 SEQ_STOP_NOTE(device, i, note, vel);
258 vm->deallocateVoice(i);
262 printfdebug(
"Note OFF >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel);
270 while ((i=vm->search(chn,note))!=-1)
271 SEQ_KEY_PRESSURE(device, i, note,vel);
276 if (chn==PERCUSSION_CHANNEL)
return;
279 while ((i=vm->search(chn))!=-1)
280 SEQ_SET_PATCH(device,i,map->
patch(chn,
patch));
289 while ((i=vm->search(chn))!=-1)
290 SEQ_CHN_PRESSURE(device, i , vel);
292 chnpressure[chn]=vel;
297 chnbender[chn]=((int)msb<<7) | (lsb & 0x7F);
301 while ((i=vm->search(chn))!=-1)
302 SEQ_BENDER(device, i, chnbender[chn]);
308 if ((ctl==11)||(ctl==7))
310 v=(v*volumepercentage)/100;
315 while ((i=vm->search(chn))!=-1)
316 SEQ_CONTROL(device, i, ctl, v);
318 chncontroller[chn][ctl]=v;
328 if ((dir==NULL)||(dir[0]==0))
return;
329 if (deleteFMPatchesDirectory)
330 free((
char *)FMPatchesDirectory);
332 FMPatchesDirectory = strdup(dir);
334 deleteFMPatchesDirectory=1;
339 #ifdef HAVE_OSS_SUPPORT
340 int fd=open(
"/dev/mixer0",O_RDWR,0);
345 if (ioctl(fd,MIXER_WRITE(SOUND_MIXER_SYNTH),&a) == -1)
346 printfdebug(
"ERROR writing to mixer\n");
353 const char *FMOut::FMPatchesDirectory =
"/etc";
354 int FMOut::deleteFMPatchesDirectory = 0;