patchload.c
上传用户:nini_0081
上传日期:2022-07-21
资源大小:2628k
文件大小:10k
源码类别:

多媒体编程

开发平台:

DOS

  1. /************************************************************************
  2.    patchload.c  --  loads patches for playmidi package
  3.    Some of this code was adapted from code written by Hannu Solovainen
  4.    Copyright (C) 1994-1996 Nathan I. Laredo
  5.    This program is modifiable/redistributable under the terms
  6.    of the GNU General Public Licence.
  7.    You should have received a copy of the GNU General Public License
  8.    along with this program; if not, write to the Free Software
  9.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  10.    Send your comments and all your spare pocket change to
  11.    laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC 1, BOX 709, 2401
  12.    Kelly Drive, Lackland AFB, TX 78236-5128, USA.
  13.  *************************************************************************/
  14. /*    edited by Peter Kutak            */
  15. /*    email : kutak@stonline.sk        */
  16. #if defined(linux) || defined(__FreeBSD__)
  17. #include "playmidi.h"
  18. #ifdef linux
  19. #include <linux/ultrasound.h>
  20. #else
  21. #include <machine/ultrasound.h>
  22. #endif
  23. #include <sys/stat.h>
  24. #include <fcntl.h>
  25. #include <unistd.h>
  26. #include "gmvoices.h"
  27. SEQ_USE_EXTBUF();
  28. extern int play_gus, play_sb, play_ext, playing, verbose, force8bit;
  29. extern int reverb, fmloaded[256], patchloaded[256];
  30. extern int gus_dev, sb_dev, ext_dev, seqfd, wantopl3;
  31. extern struct synth_info card_info[MAX_CARDS];
  32. static int use8bit = 0;
  33. struct pat_header {
  34.     char magic[12];
  35.     char version[10];
  36.     char description[60];
  37.     unsigned char instruments;
  38.     char voices;
  39.     char channels;
  40.     unsigned short nr_waveforms;
  41.     unsigned short master_volume;
  42.     unsigned int data_size;
  43. };
  44. struct sample_header {
  45.     char name[7];
  46.     unsigned char fractions;
  47.     int len;
  48.     int loop_start;
  49.     int loop_end;
  50.     unsigned short base_freq;
  51.     int low_note;
  52.     int high_note;
  53.     int base_note;
  54.     short detune;
  55.     unsigned char panning;
  56.     unsigned char envelope_rate[6];
  57.     unsigned char envelope_offset[6];
  58.     unsigned char tremolo_sweep;
  59.     unsigned char tremolo_rate;
  60.     unsigned char tremolo_depth;
  61.     unsigned char vibrato_sweep;
  62.     unsigned char vibrato_rate;
  63.     unsigned char vibrato_depth;
  64.     char modes;
  65.     short scale_frequency;
  66.     unsigned short scale_factor;
  67. };
  68. struct patch_info *patch;
  69. int spaceleft, totalspace;
  70. void gus_reload_8_bit();
  71. void gus_load(pgm)
  72. int pgm;
  73. {
  74.     int i, j, patfd, offset;
  75.     struct pat_header header;
  76.     struct sample_header sample;
  77.     char buf[256], name[256];
  78.     struct stat info;
  79.     if (pgm < 0) {
  80. use8bit = force8bit;
  81. GUS_NUMVOICES(gus_dev, (card_info[gus_dev].nr_voices = 32));
  82. SEQ_DUMPBUF();
  83. for (i = 0; i < 256; i++)
  84.     patchloaded[i] = 0;
  85. if (ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &gus_dev) == -1)
  86. {
  87.     /* error: should quit */
  88. }
  89. spaceleft = gus_dev;
  90. ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &spaceleft);
  91. totalspace = spaceleft;
  92.     }
  93.     if (patchloaded[pgm] < 0)
  94. return;
  95.     if (patchloaded[pgm] == 1)
  96. return;
  97.     if (gmvoice[pgm] == NULL) {
  98. patchloaded[pgm] = -1;
  99. return;
  100.     }
  101.     sprintf(name, PATCH_PATH1 "/%s.pat", gmvoice[pgm]);
  102.     if (stat(name, &info) == -1) {
  103. sprintf(name, PATCH_PATH2 "/%s.pat", gmvoice[pgm]);
  104. if (stat(name, &info) == -1)
  105.     return;
  106.     }
  107.     if ((patfd = open(name, O_RDONLY, 0)) == -1)
  108. return;
  109.     if (spaceleft < info.st_size) {
  110. if (!use8bit)
  111.     gus_reload_8_bit();
  112. if (use8bit)
  113.     if (spaceleft < info.st_size / 2) {
  114. close(patfd);
  115. patchloaded[pgm] = -1; /* no space for patch */
  116. return;
  117.     }
  118.     }
  119.     if (read(patfd, buf, 0xef) != 0xef) {
  120. close(patfd);
  121. return;
  122.     }
  123.     memcpy((char *) &header, buf, sizeof(header));
  124.     if (strncmp(header.magic, "GF1PATCH110", 12)) {
  125. close(patfd);
  126. return;
  127.     }
  128.     if (strncmp(header.version, "ID#000002", 10)) {
  129. close(patfd);
  130. return;
  131.     }
  132.     header.nr_waveforms = *(unsigned short *) &buf[85];
  133.     header.master_volume = *(unsigned short *) &buf[87];
  134.     offset = 0xef;
  135.     for (i = 0; i < header.nr_waveforms; i++) {
  136. if (lseek(patfd, offset, 0) == -1) {
  137.     close(patfd);
  138.     return;
  139. }
  140. if (read(patfd, &buf, sizeof(sample)) != sizeof(sample)) {
  141.     close(patfd);
  142.     return;
  143. }
  144. memcpy((char *) &sample, buf, sizeof(sample));
  145. /*
  146.  * Since some fields of the patch record are not 32bit aligned, we must
  147.  * handle them specially.
  148.  */
  149. sample.low_note = *(int *) &buf[22];
  150. sample.high_note = *(int *) &buf[26];
  151. sample.base_note = *(int *) &buf[30];
  152. sample.detune = *(short *) &buf[34];
  153. sample.panning = (unsigned char) buf[36];
  154. memcpy(sample.envelope_rate, &buf[37], 6);
  155. memcpy(sample.envelope_offset, &buf[43], 6);
  156. sample.tremolo_sweep = (unsigned char) buf[49];
  157. sample.tremolo_rate = (unsigned char) buf[50];
  158. sample.tremolo_depth = (unsigned char) buf[51];
  159. sample.vibrato_sweep = (unsigned char) buf[52];
  160. sample.vibrato_rate = (unsigned char) buf[53];
  161. sample.vibrato_depth = (unsigned char) buf[54];
  162. sample.modes = (unsigned char) buf[55];
  163. sample.scale_frequency = *(short *) &buf[56];
  164. sample.scale_factor = *(unsigned short *) &buf[58];
  165. offset = offset + 96;
  166. patch = (struct patch_info *) malloc(sizeof(*patch) + sample.len);
  167. if (patch == NULL) {
  168.     close(patfd);
  169.     return;
  170. }
  171. patch->key = GUS_PATCH;
  172. patch->device_no = gus_dev;
  173. patch->instr_no = pgm;
  174. patch->mode = sample.modes | WAVE_TREMOLO |
  175.     WAVE_VIBRATO | WAVE_SCALE;
  176. patch->len = (use8bit ? sample.len / 2 : sample.len);
  177. patch->loop_start =
  178.     (use8bit ? sample.loop_start / 2 : sample.loop_start);
  179. patch->loop_end = (use8bit ? sample.loop_end / 2 : sample.loop_end);
  180. patch->base_note = sample.base_note;
  181. patch->high_note = sample.high_note;
  182. patch->low_note = sample.low_note;
  183. patch->base_freq = sample.base_freq;
  184. patch->detuning = sample.detune;
  185. patch->panning = (sample.panning - 7) * 16;
  186. memcpy(patch->env_rate, sample.envelope_rate, 6);
  187. for (j = 0; j < 6; j++) /* tone things down slightly */
  188.     patch->env_offset[j] =
  189. (736 * sample.envelope_offset[j] + 384) / 768;
  190. if (reverb)
  191.     if (pgm < 120)
  192. patch->env_rate[3] = (2 << 6) | (12 - (reverb >> 4));
  193.     else if (pgm > 127)
  194. patch->env_rate[1] = (3 << 6) | (63 - (reverb >> 1));
  195. patch->tremolo_sweep = sample.tremolo_sweep;
  196. patch->tremolo_rate = sample.tremolo_rate;
  197. patch->tremolo_depth = sample.tremolo_depth;
  198. patch->vibrato_sweep = sample.vibrato_sweep;
  199. patch->vibrato_rate = sample.vibrato_rate;
  200. patch->vibrato_depth = sample.vibrato_depth;
  201. patch->scale_frequency = sample.scale_frequency;
  202. patch->scale_factor = sample.scale_factor;
  203. patch->volume = header.master_volume;
  204. if (lseek(patfd, offset, 0) == -1) {
  205.     close(patfd);
  206.     return;
  207. }
  208. if (read(patfd, patch->data, sample.len) != sample.len) {
  209.     close(patfd);
  210.     return;
  211. }
  212. if (patch->mode & WAVE_16_BITS && use8bit) {
  213.     patch->mode &= ~WAVE_16_BITS;
  214.     /* cut out every other byte to make 8-bit data from 16-bit */
  215.     for (j = 0; j < patch->len; j++)
  216. patch->data[j] = patch->data[1 + j * 2];
  217. }
  218. SEQ_WRPATCH(patch, sizeof(*patch) + patch->len);
  219. free(patch);
  220. offset = offset + sample.len;
  221.     }
  222.     close(patfd);
  223.     spaceleft = gus_dev;
  224.     ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &spaceleft);
  225.     patchloaded[pgm] = 1;
  226.     return;
  227. }
  228. void gus_reload_8_bit()
  229. {
  230.     int i;
  231.     if (ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &gus_dev) == -1) 
  232.     {
  233. /* error: should quit */
  234.     }
  235.     spaceleft = gus_dev;
  236.     ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &spaceleft);
  237.     totalspace = spaceleft;
  238.     use8bit = 1;
  239.     for (i = 0; i < 256; i++)
  240. if (patchloaded[i] > 0) {
  241.     patchloaded[i] = 0;
  242.     gus_load(i);
  243. }
  244. }
  245. void adjustfm(buf, key)
  246. char *buf;
  247. int key;
  248. {
  249.     unsigned char pan = ((rand() % 3) + 1) << 4;
  250.     if (key == FM_PATCH) {
  251. buf[39] &= 0xc0;
  252. if (buf[46] & 1)
  253.     buf[38] &= 0xc0;
  254. buf[46] = (buf[46] & 0xcf) | pan;
  255. if (reverb) {
  256.     unsigned val;
  257.     val = buf[43] & 0x0f;
  258.     if (val > 0)
  259. val--;
  260.     buf[43] = (buf[43] & 0xf0) | val;
  261. }
  262.     } else {
  263. int mode;
  264. if (buf[46] & 1)
  265.     mode = 2;
  266. else
  267.     mode = 0;
  268. if (buf[57] & 1)
  269.     mode++;
  270. buf[50] &= 0xc0;
  271. if (mode == 3)
  272.     buf[49] &= 0xc0;
  273. if (mode == 1)
  274.     buf[39] &= 0xc0;
  275. if (mode == 2 || mode == 3)
  276.     buf[38] &= 0xc0;
  277. buf[46] = (buf[46] & 0xcf) | pan;
  278. buf[57] = (buf[57] & 0xcf) | pan;
  279. if (mode == 1 && reverb) {
  280.     unsigned val;
  281.     val = buf[43] & 0x0f;
  282.     if (val > 0)
  283. val--;
  284.     buf[43] = (buf[43] & 0xf0) | val;
  285.     val = buf[54] & 0x0f;
  286.     if (val > 0)
  287. val--;
  288.     buf[54] = (buf[54] & 0xf0) | val;
  289. }
  290.     }
  291. }
  292. void loadfm()
  293. {
  294.     int sbfd, i, n, voice_size, data_size;
  295.     char buf[60];
  296.     struct sbi_instrument instr;
  297.     for (i = 0; i < 256; i++)
  298. fmloaded[i] = 0;
  299.     srand(getpid());
  300.     if (wantopl3) {
  301. voice_size = 60;
  302. sbfd = open(O3MELODIC, O_RDONLY, 0);
  303.     } else {
  304. voice_size = 52;
  305. sbfd = open(SBMELODIC, O_RDONLY, 0);
  306.     }
  307.     if (sbfd == -1)
  308.     {
  309.         /* error: should quit */
  310.     }
  311.     instr.device = sb_dev;
  312.     for (i = 0; i < 128; i++) {
  313. if (read(sbfd, buf, voice_size) != voice_size)
  314. {
  315.     /* error: should quit */
  316. }
  317. instr.channel = i;
  318. if (strncmp(buf, "4OP", 3) == 0) {
  319.     instr.key = OPL3_PATCH;
  320.     data_size = 22;
  321. } else {
  322.     instr.key = FM_PATCH;
  323.     data_size = 11;
  324. }
  325. fmloaded[i] = instr.key;
  326. adjustfm(buf, instr.key);
  327. for (n = 0; n < 32; n++)
  328.     instr.operators[n] = (n < data_size) ? buf[36 + n] : 0;
  329. SEQ_WRPATCH(&instr, sizeof(instr));
  330.     }
  331.     close(sbfd);
  332.     if (wantopl3)
  333. sbfd = open(O3DRUMS, O_RDONLY, 0);
  334.     else
  335. sbfd = open(SBDRUMS, O_RDONLY, 0);
  336.     for (i = 128; i < 175; i++) {
  337. if (read(sbfd, buf, voice_size) != voice_size)
  338. {
  339.     /* error: should quit */
  340. }
  341. instr.channel = i;
  342. if (strncmp(buf, "4OP", 3) == 0) {
  343.     instr.key = OPL3_PATCH;
  344.     data_size = 22;
  345. } else {
  346.     instr.key = FM_PATCH;
  347.     data_size = 11;
  348. }
  349. fmloaded[i] = instr.key;
  350. adjustfm(buf, instr.key);
  351. for (n = 0; n < 32; n++)
  352.     instr.operators[n] = (n < data_size) ? buf[n + 36] : 0;
  353. SEQ_WRPATCH(&instr, sizeof(instr));
  354.     }
  355.     close(sbfd);
  356. }
  357. #endif /* linux || FreeBSD */