]> 4ch.mooo.com Git - 16.git/blob - src/testsnd.c
wwww
[16.git] / src / testsnd.c
1 /* test.c
2  *
3  * Adlib OPL2/OPL3 FM synthesizer chipset test program.
4  * (C) 2010-2012 Jonathan Campbell.
5  * Hackipedia DOS library.
6  *
7  * This code is licensed under the LGPL.
8  * <insert LGPL legal text here>
9  *
10  * Compiles for intended target environments:
11  *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
12  *
13  * This test program uses a "text user interface" to allow you to play
14  * with the OPL2/OPL3 chipset and it's parameters. Some "instruments"
15  * are preset for you if you want to make noise faster.
16  */
17  
18 #include <stdio.h>
19 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <malloc.h>
24 #include <ctype.h>
25 #include <fcntl.h>
26 #include <dos.h>
27
28 #include <hw/vga/vga.h>
29 #include <hw/dos/dos.h>
30 #include <hw/8254/8254.h>               /* 8254 timer */
31 #include <hw/vga/vgagui.h>
32 #include <hw/vga/vgatty.h>
33 #include <hw/adlib/adlib.h>
34
35 static unsigned int musical_scale[18] = {
36         0x1B0,                  /* E */
37         0x1CA,                  /* F */
38         0x1E5,                  /* f# */
39         0x202,                  /* G */
40         0x220,                  /* G# */
41         0x241,                  /* A */
42         0x263,                  /* A# */
43         0x287,                  /* B */
44         0x2AE,                  /* C */
45
46         0x2B0,                  /* E */
47         0x2CA,                  /* F */
48         0x2E5,                  /* f# */
49         0x302,                  /* G */
50         0x320,                  /* G# */
51         0x341,                  /* A */
52         0x363,                  /* A# */
53         0x387,                  /* B */
54         0x3AE,                  /* C */
55 };
56
57 int main(int argc,char **argv) {
58         int i,loop,redraw,c,cc,selector=0,redrawln=0,hselect=0,selectsub=0;
59         VGA_ALPHA_PTR vga;
60         char tmp[128];
61
62         printf("ADLIB FM test program\n");
63
64         if (!probe_vga()) {
65                 printf("Cannot init VGA\n");
66                 return 1;
67         }
68         if (!init_adlib()) {
69                 printf("Cannot init library\n");
70                 return 1;
71         }
72
73         int10_setmode(3);
74
75         /* for VGA: free up space if needed by going to 80x50 */
76         if (adlib_fm_voices > 9)
77                 vga_bios_set_80x50_text();
78
79         memset(adlib_fm,0,sizeof(adlib_fm));
80         memset(&adlib_reg_bd,0,sizeof(adlib_reg_bd));
81         for (i=0;i < adlib_fm_voices;i++) {
82                 struct adlib_fm_operator *f;
83                 f = &adlib_fm[i].mod;
84                 f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;
85                 f = &adlib_fm[i].car;
86                 f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;
87         }
88
89         for (i=0;i < adlib_fm_voices;i++) {
90                 struct adlib_fm_operator *f;
91
92                 f = &adlib_fm[i].mod;
93                 f->mod_multiple = 1;
94                 f->total_level = 63 - 16;
95                 f->attack_rate = 15;
96                 f->decay_rate = 0;
97                 f->sustain_level = 7;
98                 f->release_rate = 7;
99                 f->f_number = musical_scale[i%18];
100                 f->octave = 4;
101                 f->key_on = 0;
102
103                 f = &adlib_fm[i].car;
104                 f->mod_multiple = 1;
105                 f->total_level = 63 - 16;
106                 f->attack_rate = 15;
107                 f->decay_rate = 0;
108                 f->sustain_level = 7;
109                 f->release_rate = 7;
110                 f->f_number = 0;
111                 f->octave = 0;
112                 f->key_on = 0;
113         }
114
115         adlib_apply_all();
116
117         vga_write_color(0x07);
118         vga_clear();
119
120         loop=1;
121         redraw=1;
122         while (loop) {
123                 if (redraw || redrawln) {
124                         if (redraw) {
125                                 for (vga=vga_alpha_ram,cc=0;cc < (80*vga_height);cc++) *vga++ = 0x1E00 | 177;
126                                 vga_moveto(0,0);
127                                 vga_write_color(0x1F);
128                                 sprintf(tmp,"Adlib FM, %u-voice %s. Use Z & X to adj  F10=PRESET F1=QUIET ",adlib_fm_voices,
129                                         (adlib_flags & ADLIB_FM_OPL3) ? "OPL3" :
130                                         (adlib_flags & ADLIB_FM_DUAL_OPL2) ? "Dual OPL2" : "OPL2");
131                                 vga_write(tmp);
132                                 if (adlib_flags & ADLIB_FM_OPL3) vga_write("F2=OPL3 off ");
133                         }
134
135                         if (redrawln || redraw) {
136                                 struct adlib_reg_bd *bd = &adlib_reg_bd;
137                                 static const char *hsel_str[18] = {
138                                         "Amplitude modulatation",
139                                         "Vibrato",
140                                         "Sustain",
141                                         "Key scaling rate",
142                                         "Modulator frequency multiple",
143                                         "Level key scaling",
144                                         "Total level",
145                                         "Attack rate",
146                                         "Decay rate",
147                                         "Sustain level",
148                                         "Release rate",
149                                         "KEY ON",
150                                         "Octave",
151                                         "F-Number",
152                                         "Feedback",
153                                         "Connection (operator 1 -> operator 2)",
154                                         "Waveform",
155                                         "Channel mapping (OPL3)"
156                                 };
157
158                                 vga_write_color(0x1A);
159
160                                 vga_moveto(0,2);
161                                 sprintf(tmp,"AM=%u VB=%u RYTHM=%u BAS=%u SNA=%u TOM=%u CYM=%u HI=%u\n",
162                                         bd->am_depth,
163                                         bd->vibrato_depth,
164                                         bd->rythm_enable,
165                                         bd->bass_drum_on,
166                                         bd->snare_drum_on,
167                                         bd->tom_tom_on,
168                                         bd->cymbal_on,
169                                         bd->hi_hat_on);
170                                 vga_write(tmp);
171
172                                 vga_moveto(0,3);
173                                 vga_write("                                                       ");
174                                 vga_moveto(0,3);
175                                 vga_write(hsel_str[hselect]);
176
177                                 vga_moveto(0,4);
178                                 vga_write_color(hselect ==  0 ? 0x70 : 0x1E);           vga_write("AM ");
179                                 vga_write_color(hselect ==  1 ? 0x70 : 0x1E);           vga_write("VB ");
180                                 vga_write_color(hselect ==  2 ? 0x70 : 0x1E);           vga_write("SUST ");
181                                 vga_write_color(hselect ==  3 ? 0x70 : 0x1E);           vga_write("KSR ");
182                                 vga_write_color(hselect ==  4 ? 0x70 : 0x1E);           vga_write("MMUL ");
183                                 vga_write_color(hselect ==  5 ? 0x70 : 0x1E);           vga_write("LKS ");
184                                 vga_write_color(hselect ==  6 ? 0x70 : 0x1E);           vga_write("TL ");
185                                 vga_write_color(hselect ==  7 ? 0x70 : 0x1E);           vga_write("AR ");
186                                 vga_write_color(hselect ==  8 ? 0x70 : 0x1E);           vga_write("DR ");
187                                 vga_write_color(hselect ==  9 ? 0x70 : 0x1E);           vga_write("SL ");
188                                 vga_write_color(hselect == 10 ? 0x70 : 0x1E);           vga_write("RR ");
189                                 vga_write_color(hselect == 11 ? 0x70 : 0x1E);           vga_write("KEY ");
190                                 vga_write_color(hselect == 12 ? 0x70 : 0x1E);           vga_write("OCT ");
191                                 vga_write_color(hselect == 13 ? 0x70 : 0x1E);           vga_write("FNUM ");
192                                 vga_write_color(hselect == 14 ? 0x70 : 0x1E);           vga_write("FEED ");
193                                 vga_write_color(hselect == 15 ? 0x70 : 0x1E);           vga_write("CON ");
194                                 vga_write_color(hselect == 16 ? 0x70 : 0x1E);           vga_write("WV ");
195                                 vga_write_color(hselect == 17 ? 0x70 : 0x1E);           vga_write("ABCD ");
196
197                                 for (i=0;i < adlib_fm_voices;i++) {
198                                         struct adlib_fm_operator *f;
199                                         double freq;
200                                         
201                                         f = &adlib_fm[i].mod;
202                                         vga_moveto(0,5+i*2);
203                                         freq = adlib_fm_op_to_freq(f);
204                                         vga_write_color(i == selector && selectsub == 0 ? 0x70 : 0x1E);
205                                         cc = sprintf(tmp,"%u  %u  %u    %u   %-2u   %u   %-2u %-2u %-2u %-2u %-2u %u   %u   %-4u %u    %u   %u  %c%c%c%c %u %.1fHz ",
206                                                 f->am,                  f->vibrato,             f->sustain,             f->key_scaling_rate,
207                                                 f->mod_multiple,        f->level_key_scale,     f->total_level,         f->attack_rate,
208                                                 f->decay_rate,          f->sustain_level,       f->release_rate,        f->key_on,
209                                                 f->octave,              f->f_number,            f->feedback,            f->connection,
210                                                 f->waveform,            f->ch_a?'*':'-',        f->ch_b?'*':'-',        f->ch_c?'*':'-',
211                                                 f->ch_d?'*':'-',        i+1,                    freq);
212                                         vga_write(tmp);
213
214                                         f = &adlib_fm[i].car;
215                                         vga_moveto(0,5+i*2+1);
216                                         vga_write_color(i == selector && selectsub == 1 ? 0x70 : 0x1E);
217                                         cc = sprintf(tmp,"%u  %u  %u    %u   %-2u   %u   %-2u %-2u %-2u %-2u %-2u                       %u       CAR   ",
218                                                 f->am,                  f->vibrato,             f->sustain,             f->key_scaling_rate,
219                                                 f->mod_multiple,        f->level_key_scale,     f->total_level,         f->attack_rate,
220                                                 f->decay_rate,          f->sustain_level,       f->release_rate,        f->waveform);
221                                         vga_write(tmp);
222                                 }
223                         }
224
225                         redrawln = 0;
226                         redraw = 0;
227                 }
228
229                 if (kbhit()) {
230                         c = getch();
231                         if (c == 0) c = getch() << 8;
232
233                         if (c == 27) {
234                                 loop = 0;
235                         }
236                         else if (c == 0x3B00) { /* F1 */
237                                 for (i=0;i < adlib_fm_voices;i++) {
238                                         adlib_fm[i].mod.key_on = 0;
239                                         adlib_fm[i].car.key_on = 0;
240                                         adlib_update_groupA0(i,&adlib_fm[i]);
241                                 }
242                                 redrawln = 1;
243                         }
244                         else if (c == 0x3C00) { /* F2 */
245                                 if (adlib_flags & ADLIB_FM_OPL3) {
246                                         shutdown_adlib_opl3();
247                                         int10_setmode(3);
248                                         redraw = 1;
249                                 }
250                         }
251                         else if (c == 0x4400) { /* F10 */
252                                 unsigned short op = adlib_voice_to_op[selector];
253
254                                 vga_write_color(0x07);
255                                 vga_clear();
256                                 vga_moveto(0,0);
257
258                                 vga_write("Choose an instrument to load into the channel:\n");
259                                 vga_write(" 1. Violin     2. Piano     3. Harpsichord     4. Horn      5. Deep bass drum\n");
260                                 vga_write(" 6. Small drum \n");
261                                 vga_write_sync();
262
263                                 c = getch();
264
265                                 if (c == '1')
266                                         adlib_fm[selector] =
267                                                 (adlib_flags & ADLIB_FM_OPL3 ?
268                                                  adlib_fm_preset_violin_opl3 : adlib_fm_preset_violin_opl2);
269                                 else if (c == '2')
270                                         adlib_fm[selector] = adlib_fm_preset_piano;
271                                 else if (c == '3')
272                                         adlib_fm[selector] = adlib_fm_preset_harpsichord;
273                                 else if (c == '4')
274                                         adlib_fm[selector] = adlib_fm_preset_horn;
275                                 else if (c == '5')
276                                         adlib_fm[selector] = adlib_fm_preset_deep_bass_drum;
277                                 else if (c == '6')
278                                         adlib_fm[selector] = adlib_fm_preset_small_drum;
279
280                                 adlib_update_groupA0(selector,&adlib_fm[selector]);
281                                 adlib_update_groupC0(selector,&adlib_fm[selector]);
282                                 adlib_update_operator(op,&adlib_fm[selector].mod);
283                                 adlib_update_operator(op+3,&adlib_fm[selector].car);
284
285                                 redraw = 1;
286                         }
287                         else if (c == ' ') {
288                                 adlib_fm[selector].mod.key_on ^= 1;
289                                 adlib_update_groupA0(selector,&adlib_fm[selector]);
290                                 redrawln=1;
291                         }
292                         else if (c == 'a') {
293                                 if (hselect == 17) {
294                                         struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_a ^= 1;
295                                         adlib_update_groupC0(selector,&adlib_fm[selector]);
296                                 }
297                                 else {
298                                         adlib_reg_bd.am_depth ^= 1;
299                                         adlib_update_bd(&adlib_reg_bd);
300                                 }
301                                 redrawln = 1;
302                         }
303                         else if (c == 'v') {
304                                 adlib_reg_bd.vibrato_depth ^= 1;
305                                 adlib_update_bd(&adlib_reg_bd);
306                                 redrawln = 1;
307                         }
308                         else if (c == 'r') {
309                                 adlib_reg_bd.rythm_enable ^= 1;
310                                 adlib_update_bd(&adlib_reg_bd);
311                                 redrawln = 1;
312                         }
313                         else if (c == 'b') {
314                                 if (hselect == 17) {
315                                         struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_b ^= 1;
316                                         adlib_update_groupC0(selector,&adlib_fm[selector]);
317                                 }
318                                 else {
319                                         adlib_reg_bd.bass_drum_on ^= 1;
320                                         adlib_update_bd(&adlib_reg_bd);
321                                 }
322                                 redrawln = 1;
323                         }
324                         else if (c == 's') {
325                                 adlib_reg_bd.snare_drum_on ^= 1;
326                                 adlib_update_bd(&adlib_reg_bd);
327                                 redrawln = 1;
328                         }
329                         else if (c == 't') {
330                                 adlib_reg_bd.tom_tom_on ^= 1;
331                                 adlib_update_bd(&adlib_reg_bd);
332                                 redrawln = 1;
333                         }
334                         else if (c == 'c') {
335                                 if (hselect == 17) {
336                                         struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_c ^= 1;
337                                         adlib_update_groupC0(selector,&adlib_fm[selector]);
338                                 }
339                                 else {
340                                         adlib_reg_bd.cymbal_on ^= 1;
341                                         adlib_update_bd(&adlib_reg_bd);
342                                 }
343                                 redrawln = 1;
344                         }
345                         else if (c == 'd') {
346                                 if (hselect == 17) {
347                                         struct adlib_fm_operator *f = &adlib_fm[selector].mod; f->ch_d ^= 1;
348                                         adlib_update_groupC0(selector,&adlib_fm[selector]);
349                                 }
350                                 else {
351                                 }
352                                 redrawln = 1;
353                         }
354                         else if (c == 'h') {
355                                 adlib_reg_bd.hi_hat_on ^= 1;
356                                 adlib_update_bd(&adlib_reg_bd);
357                                 redrawln = 1;
358                         }
359                         else if (c == 'z' || c == 'Z' || c == 'x' || c == 'X') {
360                                 struct adlib_fm_operator *f;
361                                 int dec = tolower(c) == 'z';
362                                 unsigned short operator;
363
364                                 switch (hselect) {
365                                         case 11:selectsub = 0;
366                                                 break;
367                                 }
368
369                                 if (selectsub) f = &adlib_fm[selector].car;
370                                 else           f = &adlib_fm[selector].mod;
371                                 operator = adlib_voice_to_op[selector] + (selectsub*3);
372
373                                 switch (hselect) {
374                                         case 0:         f->am ^= 1;                     adlib_update_group20(operator,f); break;
375                                         case 11:        f->key_on ^= 1;                 adlib_update_groupA0(selector,&adlib_fm[selector]); break;
376                                         case 1:         f->vibrato ^= 1;                adlib_update_group20(operator,f); break;
377                                         case 2:         f->sustain ^= 1;                adlib_update_group20(operator,f); break;
378                                         case 15:        f->connection ^= 1;             adlib_update_group20(operator,f); break;
379                                         case 3:         f->key_scaling_rate ^= 1;       adlib_update_group20(operator,f); break;
380
381                                         case 4:         if (dec) f->mod_multiple--; else f->mod_multiple++;
382                                                         adlib_update_group20(operator,f); break;
383                                         case 5:         if (dec) f->level_key_scale--; else f->level_key_scale++;
384                                                         adlib_update_group40(operator,f); break;
385                                         case 6:         if (dec) f->total_level--; else f->total_level++;
386                                                         adlib_update_group40(operator,f); break;
387                                         case 7:         if (dec) f->attack_rate--; else f->attack_rate++;
388                                                         adlib_update_group60(operator,f); break;
389                                         case 8:         if (dec) f->decay_rate--; else f->decay_rate++;
390                                                         adlib_update_group60(operator,f); break;
391                                         case 9:         if (dec) f->sustain_level--; else f->sustain_level++;
392                                                         adlib_update_group80(operator,f); break;
393                                         case 10:        if (dec) f->release_rate--; else f->release_rate++;
394                                                         adlib_update_group80(operator,f); break;
395                                         case 12:        if (dec) f->octave--; else f->octave++;
396                                                         adlib_update_groupA0(selector,&adlib_fm[selector]); break;
397                                         case 13:        if (dec) f->f_number--; else f->f_number++;
398                                                         adlib_update_groupA0(selector,&adlib_fm[selector]); break;
399                                         case 14:        if (dec) f->feedback--; else f->feedback++;
400                                                         adlib_update_groupC0(selector,&adlib_fm[selector]); break;
401                                         case 16:        if (dec) f->waveform--; else f->waveform++;
402                                                         adlib_update_groupE0(operator,f); break;
403                                 };
404
405                                 redrawln=1;
406                         }
407                         else if (c == 0x4800) {
408                                 if (selectsub && !(hselect >= 11 && hselect <= 15)) {
409                                         selectsub = 0;
410                                         redrawln = 1;
411                                 }
412                                 else if (selector > 0) {
413                                         selectsub = !(hselect >= 11 && hselect <= 15);
414                                         selector--;
415                                         redrawln = 1;
416                                 }
417                         }
418                         else if (c == 0x4B00) {
419                                 if (hselect > 0) {
420                                         hselect--;
421                                         redrawln=1;
422                                 }
423                         }
424                         else if (c == 0x4D00) {
425                                 if (hselect < 17) {
426                                         hselect++;
427                                         redrawln=1;
428                                 }
429                         }
430                         else if (c == 0x5000) {
431                                 if (selectsub == 0 && !(hselect >= 11 && hselect <= 15)) {
432                                         selectsub = 1;
433                                         redrawln = 1;
434                                 }
435                                 else if ((selector+1) < adlib_fm_voices) {
436                                         selectsub = 0;
437                                         selector++;
438                                         redrawln=1;
439                                 }
440                         }
441
442                 }
443         }
444
445         shutdown_adlib();
446         int10_setmode(3);
447
448         return 0;
449 }
450