/project/jni/sdl_mixer/native_midi_gpl/patchload.c

https://github.com/aichunyu/FFPlayer · C · 412 lines · 332 code · 52 blank · 28 comment · 88 complexity · 5bce28ebb7f718e46d0c98659287f937 MD5 · raw file

  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 */